]
Xi Zhang commented on HHH-6349:
-------------------------------
I have the same problem on usage of the (unidirectional)OneToMany annotation like
described above. As I also tried the another possiblity to audit the OneToMany by using a
"fake" bidirectional reference with the annotation @AuditMappedBy, I got nearly
same result, instead of missing entry in the AuditJoinTable I had the Null-values in the
join column.
As a workaround I defined a real bidirectional relation(OneToMany +ManyToOne) between the
entities, then I can audit the entities updates correctly.
Is it the reason, that the "fake" ManyToOne relation that is
private(updatable=false) could not be merged/updated from detached entities to attached
entities as the merge() method's semantic defined in JPA specification.
I think, the (unidirectional)OneToMany annotation is the critical path in the ENVERS.
AuditJoinTable rows missing when detached entities with collections
are merged into the persistence context
-----------------------------------------------------------------------------------------------------------
Key: HHH-6349
URL:
https://hibernate.onjira.com/browse/HHH-6349
Project: Hibernate ORM
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.
For more information on JIRA, see: