What's the difference between @NotAudited and RelationTargetAuditMode.NOT_AUDITED in Hibernate EnVers?
@NotAudited
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@OneToMany(mappedBy = "booking")
@OrderBy("bookingOrder")
private List<CustomerBooking> customerBookingList = new LinkedList<CustomerBooking>();
Why use both? is it good to use both or would one suffice?
Solution 1:
Use NotAudited on fields when you don't want the value / relationship to be audited at all. I believe you can use this on a field with or without a relationship such as OneToMany, ManyToMany, or just Column. Use RelationTargetAuditMode.NOT_AUDITED on a relationship field if you want the value to be audited, but not the entity on the other side of the relationship. For example you want the ID / key value audited, but not the related table.
You can also apply the RelationTargetAuditMode to the entire class, which I believe just says for all relationships in the class don't audit the other end. This confused me as I was mistakenly using this annotation to mean don't audit the entity below, which is not what it means. Just don't have an Audit annotation on an entity class at all if you don't want the entity audited. On other audited entities that refer to the entity you'll have to either use NotAudited or RelationTargetAuditMode.NOT_AUDITED to the relationship field.
The official documentation is not great about this topic (http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch15.html) and doesn't even mention NotAudited at all.
In my past projects I've had a need to audit a very specific set of tables and not others so I needed to use these annotations. I have foreign key relationships to some of my non-audited entities from some audited entities. I often use the RelationTargetAuditMode.NOT_AUDITED annotation so that at least I audit the foreign key value / ID, just not the entity on the other end of the relationship. If you don't have this annotation you'll get a runtime exception where ENVERS tries to insert an audit record into an audit table for the non-audited entity and that table won't exist. I use the NotAudited annotation for a few ManyToMany join table relationships that I just don't need to audit and there is nothing on the audited entity table itself to record (no foreign key ID / value).
Oh yeah - the docs don't say what happens if you use both (not sure which one has priority), but I don't think using both simultaneously on a given field is intended. Use one or the other.
Solution 2:
Auditing the target entity and its relations are two separate things. So it depends on what you need. From Hibernate Envers - Easy Entity Auditing documentation:
If you want to audit a relation, where the target entity is not audited (that is the case for example with dictionary-like entities, which don't change and don't have to be audited), just annotate it with @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED). Then, when reading historic versions of your entity, the relation will always point to the "current" related entity.
Solution 3:
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
has only one usage: When you have audited entity owning the relationship to not audited entity and you want info in audit data about the id of not audited entity. Let's say that CustomerBooking
is audited and Hotel class is not audited. You have two choices for Hotel field:@NotAudited
(in which case you will not have info about hotel in historical data at all) or @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
in which case you will have always the latest state of Hotel in audit data.
Note that if Hotel was audited RelationTargetAuditMode.NOT_AUDITED
will just be ignored (you will have historical data for Hotel).
@NotAudited
means "I just don't care for this field in historical data" (it won't be saved, relationship will be null, you won't see it when looking historical data about CustomerBooking
)