# Hibernate Envers ValidityAuditStrategy throws a "Cannot update previous revision for entity" exception

**URL:** <https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225>\
**Category:** Hibernate ORM\
**Created:** [February 6, 2019, 6:51am UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225 "2019-02-06T06:51:11Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sreejesh](https://avatars.discourse-cdn.com/v4/letter/s/9de0a6/32.png) [@sreejesh](https://discourse.hibernate.org/u/sreejesh)\
**Post date:** [February 6, 2019, 6:51am UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225/1 "2019-02-06T06:51:11Z")

</div>

I created a sample project & done CRUD operations. Now I added & enabled envers, set ValidityAuditStrategy. Now on trying to update existing table rows, envers throwing exception as below. Is this an Envers bug? How to go ahead for this case?

```auto
"ERROR: HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.RuntimeException: Cannot update previous revision for entity OfficeAddress_AUD and id 1
org.hibernate.AssertionFailure: Unable to perform beforeTransactionCompletion callback
	at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:905)
	at org.hibernate.engine.spi.ActionQueue.beforeTransactionCompletion(ActionQueue.java:481)
	at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2353)
	at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
	at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)"

```

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [February 6, 2019, 7:55am UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225/2 "2019-02-06T07:55:32Z")

</div>

Try to replicate it with [this test case template](http://in.relation.to/2016/01/14/hibernate-jpa-test-case-template/).

---

<div class="post-metadata">

**Author:** ![Naros](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/naros/32/19_2.png) [@Naros](https://discourse.hibernate.org/u/Naros)\
**Post date:** [February 11, 2019, 8:26pm UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225/3 "2019-02-11T20:26:02Z")

</div>

The `ValidityAuditStrategy` expects that a prior change data capture (CDC) row exists with the same primary key where the `REV_END` column is `NULL`. If no row exists with this requirement when an update to an entity occurs, this strategy will throw this exception because the prior row state cannot be updated correctly to reflect the proper chain of `REV_END` values.

So why would the prior row not exist?

One common mistake is to allow insertion of audited data through means that completely bypass the event system of Hibernate. Examples of this include direct SQL manipulation, native-queries, or even the use of Hibernate’s Stateless session.

Another common reason this can happen is when Envers is enabled on an existing database with data while using the `ValidityAuditStrategy` implementation. In short, what happens is future changes get tracked but because no prior `INSERT` operation was ever audited, the strategy asserts with this failure.

Its generally accepted practice that if you intend to enable Envers on an existing legacy database, make sure that you seed the audit tables after they’ve been generated before manipulating the entities. This makes sure that the seeded data represents the current `INSERT` snapshot of all your audited data prior to future `UPDATE` changes being applied.

---

<div class="post-metadata">

**Author:** ![sreejesh](https://avatars.discourse-cdn.com/v4/letter/s/9de0a6/32.png) [@sreejesh](https://discourse.hibernate.org/u/sreejesh)\
**Post date:** [February 18, 2019, 11:56am UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225/4 "2019-02-18T11:56:23Z")

</div>

Hi Naros,  
Noticed a bug you’re working on in this respect.  
[https://hibernate.atlassian.net/browse/HHH-8456](https://hibernate.atlassian.net/browse/HHH-8456)

If we have a big size database, can you suggest any best practice/example to seed audit tables?

---

<div class="post-metadata">

**Author:** ![Naros](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/naros/32/19_2.png) [@Naros](https://discourse.hibernate.org/u/Naros)\
**Post date:** [February 19, 2019, 12:45pm UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225/5 "2019-02-19T12:45:15Z")

</div>

The basic gist to seed the audit tables is quite straight forward.

1. Get the next `REVISION_NUMBER` sequence.
2. Insert a new row into `REVINFO` which includes the revision number from (1) and the timestamp.
3. Insert a new row into all the generated `_AUD` tables based on your current snapshot of data.

For (3) there are a couple requirements.

1. The `REVEND` field (only applicable for `ValidityAuditStrategy`) should be left `NULL`.
2. The REV field should be populated with the revision number you inserted into `REVINFO`.
3. The `REV_TYPE` field should be set to `0` to represent an insert/add operation.
4. If any audit tables have a `_MOD` field, it should be set to `1` when seeding.

The _how you get data into the audit tables_ is entirely a personal preference. The most straight forward way is to write a database script that does it.

If you already have Debezium/Kafka installed somewhere you could also look into reading a database snapshot of the tables of interest and have a set of custom sink connectors that process those events to generate the inserts accordingly too. This is definitely far more involved, requires a substantial amount of knowledge of Debezium/Kafka Connect to work, but its another viable alternative if you’re not so familiar with writing database scripts.

---

<div class="post-metadata">

**Author:** ![ts\_u](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/ts_u/32/1545_2.png) [@ts\_u](https://discourse.hibernate.org/u/ts_u)\
**Post date:** [June 12, 2021, 4:00pm UTC](https://discourse.hibernate.org/t/hibernate-envers-validityauditstrategy-throws-a-cannot-update-previous-revision-for-entity-exception/2225/6 "2021-06-12T16:00:40Z")

</div>

hello

thank you for help  
should i do all 3 steps for each row in entity\_table  
or I can insert one row in REVINFO and use that row’s id to fill all data into entity\_table\_aud and relation\_table\_aud

i had legacy database and i want to make one entity Auditable  
entity have ManyToMany relations too, which i use  
Audited(targetAuditMode = RelationTargetAuditMode.NOT\_AUDITED)

I want to use one REVISION\_NUMBER with one REVINFO for all needed data in all created \_AUD tables in the database. can i ?  
@vlad @Naros
