I have an entity with a reference to another entity, something like this:
@Entity(name = "MyCustomEntity")
@Table(name = "my_custom_entity")
public class MyCustomEntity {
@Id
Integer id;
@ManyToOne
@JoinColumn(name = "profile_id")
OtherEntity other;
}
As it turns out, business logic dictates that OtherEntity
should not be mutable in this context. Since you can still change the entity outside this context, I thought it was easiest to change the reference from MyCustomEntity
to an Envers revision.
I could replace the reference with this snippet:
@Entity(name = "MyCustomEntity")
@Table(name = "my_custom_entity")
public class MyCustomEntity {
@Id
Integer id;
Integer otherId;
Integer revision;
}
OtherEntity getOther(MyCustomEntity entity) throws Exception {
return auditReader.find(OtherEntity.class, entity.otherId, entity.revision);
}
But I'd lose a couple of Hibernate features that I'd rather have.
Is there a better way to reference an Envers revision?
Based on the fact you simply want to enforce immutability with the relationship between the two entities, why not simply make use of the
@Immutable
annotation here rather than trying to manipulate this through your model.But it's important to understand that
Immutable
in this content applies solely to ORM.Lets say you perform the following actions
MyCustomEntity
revision pointing toOtherEntity
.OtherEntity
(now has a higher revision number thanMyCustomEntity
)MyCustomEntity
(now has a higher revision number thanOtherEntity
)MyCustomEntity
with latest revision.That latest revision will point to the
OtherEntity
with modifications made in step 2. The immutability annotation simply doesn't allow changing the FK reference.Does that solve your issue?
UPDATE
That is precisely how Envers works.
The
MyCustomEntity
will only return the related association with a revision number that is equal-to or less-than its queried revision.That means if you modify
OtherEntity
and then queryMyCustomEntity
, the returned instance ofOtherEntity
would not contain those recent changes.The only time that
MyCustomEntity
would return the latest snapshot of theOtherEntity
association would be ifMyCustomEntity
is modified in the same transaction or a future transaction afterOtherEntity
.Associations are always returned with the associated entity-type having a revision number than is
<=
the queried entity's revision number.If you're changing both, then the order in which you perform those changes will play into what snapshot the relationship will return in audit queries.
If you're goal is to somehow pin a revision, there really isn't a good logical way to do that, at least not within the same transaction boundary anyway given how Envers performs its logic in a pre-commit transaction callback.