[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-6349) AuditJoinTable rows missing when detached entities with collections are merged into the persistence context

Erik-Berndt Scheper (JIRA) noreply at atlassian.com
Thu Jun 23 09:39:54 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-6349?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=42703#action_42703 ] 

Erik-Berndt Scheper commented on HHH-6349:
------------------------------------------

If the Envers {{ValidityAuditStrategy}} is used, this bug will have a severe side-effect. Subsequent deletions of referenced entities in the collections will lead to the RuntimeException "Cannot find previous revision for entity". The reason behind this is that the {{ValidityAuditStrategy}} will try to update the REVEND columns of rows in the AuditJoinTable, but it cannot find the revision in question since the rows have not been saved.

Sample stacktrace for this side-effect:

{noformat} 
DEBUG 19-05-2011 15:49:20,450 [http-thread-pool-8080-(2)] (org.hibernate.SQL) | select jb_psnhppa0_.REV as REV46_, jb_psnhppa0_.PSN_ID as PSN2_46_, jb_psnhppa0_.HPP_ID as HPP3_46_, jb_psnhppa0_.REVTYPE as REVTYPE46_, jb_psnhppa0_.REVEND as REVEND46_, jb_psnhppa0_.REVEND_TSTMP as REVEND6_46_ from JB_PSNHPPA jb_psnhppa0_ where jb_psnhppa0_.PSN_ID=? and jb_psnhppa0_.HPP_ID=? and (jb_psnhppa0_.REVEND is null)
ERROR 19-05-2011 15:49:20,668 [http-thread-pool-8080-(2)] (org.hibernate.AssertionFailure) | 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 find previous revision for entity JB_PSNHPPA and id {REV=BapRevision { id = "129483", timestamp = "1305812960200",  dateTime = "2011-05-19T15:49:20.200" auditContextId = "75557"}, Persoon_id=99620, partners_id=2837}
	at org.hibernate.envers.strategy.ValidityAuditStrategy.updateLastRevision(ValidityAuditStrategy.java:175)
	at org.hibernate.envers.strategy.ValidityAuditStrategy.performCollectionChange(ValidityAuditStrategy.java:96)
	at org.hibernate.envers.synchronization.work.PersistentCollectionChangeWorkUnit.perform(PersistentCollectionChangeWorkUnit.java:88)
	at org.hibernate.envers.synchronization.AuditProcess.executeInSession(AuditProcess.java:114)
	at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:152)
	at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543)
	at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:216)
	at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571)
	at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:250)
	at org.hibernate.transaction.synchronization.CallbackCoordinator.beforeCompletion(CallbackCoordinator.java:125)
	at org.hibernate.transaction.synchronization.HibernateSynchronizationImpl.beforeCompletion(HibernateSynchronizationImpl.java:51)
	at com.sun.jts.jta.SynchronizationImpl.before_completion(SynchronizationImpl.java:99)
	at com.sun.jts.CosTransactions.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:158)
	at com.sun.jts.CosTransactions.TopCoordinator.beforeCompletion(TopCoordinator.java:2551)
	at com.sun.jts.CosTransactions.CoordinatorTerm.commit(CoordinatorTerm.java:278)
	at com.sun.jts.CosTransactions.TerminatorImpl.commit(TerminatorImpl.java:251)
	at com.sun.jts.CosTransactions.CurrentImpl.commit(CurrentImpl.java:623)
	at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:318)
	at com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate.commitDistributedTransaction(JavaEETransactionManagerJTSDelegate.java:171)
	at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:843)
	at com.sun.enterprise.transaction.UserTransactionImpl.commit(UserTransactionImpl.java:201)
{noformat} 

> AuditJoinTable rows missing when detached entities with collections are merged into the persistence context
> -----------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-6349
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6349
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: envers
>    Affects Versions: 3.6.5, 4.0.0.Beta1
>            Reporter: Erik-Berndt Scheper
>            Assignee: Erik-Berndt Scheper
>
> Given an Entity that is audited by Envers, which contains more than one collection (e.g. two Lists); for example
> {code:title=MultipleCollectionEntity .java|borderStyle=solid}
> Entity
> @org.hibernate.envers.Audited
> public class MultipleCollectionEntity {
> 	@Id
> 	@GeneratedValue(strategy = GenerationType.IDENTITY)
> 	@Column(name = "ID", length = 10)
> 	private Long id;
> 	@Version
> 	@Column(name = "VERSION", nullable = false)
> 	private Integer version;
> 	@Column(name = "TEXT", length = 50, nullable = false)
> 	private String text;
> 	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
> 	@JoinColumn(name = "MCE_ID", nullable = false)
> 	@org.hibernate.envers.AuditJoinTable(name = "MCE_RE1_AUD", inverseJoinColumns = @JoinColumn(name = "RE1_ID"))
> 	private List<MultipleCollectionRefEntity1> refEntities1 = new ArrayList<MultipleCollectionRefEntity1>();
> 	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
> 	@JoinColumn(name = "MCE_ID", nullable = false)
> 	@org.hibernate.envers.AuditJoinTable(name = "MCE_RE2_AUD", inverseJoinColumns = @JoinColumn(name = "RE2_ID"))
> 	private List<MultipleCollectionRefEntity2> refEntities2 = new ArrayList<MultipleCollectionRefEntity2>();
> {code}
> Envers stores the audit information for additions and deletions to these Lists in AuditJoinTables (MCE_RE1_AUD and MCE_RE2_AUD). This process is driven by the Hibernate collection events; to be exact by the difference between the current contents of the collection (using event.getCollection()) and the contents of the stored snapshot of this collection (using collectionEntry.getSnapshot()).
> This works fine as long as the given entity is available in the current persistence context. 
> Unfortunately, this is not the case when detached entities are merged back into the persistence context. 
> In this case, the end result is that audit information is stored in the MultipleCollectionEntity_AUD table, in the MultipleCollectionRefEntity1_AUD table and the MultipleCollectionRefEntity2_AUD table. However, the AuditJoinTable rows are missing. 
> Effectively this means that the rows in MultipleCollectionRefEntity2_AUD are dangling and that the audit information when refEntities were added or deleted to the refEntities1 and refEntities2 collections has been irretrievably lost.
> I have prepared Envers test cases for the 3.6.x and 4.0.x versions and will be adding them shortly.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list