Hibernate envers REVTYPE not working


#1

I am using hibernate envers and this time I didn’t generate the database schema using the hbm2ddl update tool. Now when I save an entity everything is good but the Revtype is null. The REV number is working well.
Do you know why this might be happening?
Thanks in advance


#2

A typical AUD table looks like this:

create table Address_AUD (
    id bigint not null,
    REV integer not null,
    REVTYPE tinyint,
    REVEND integer,
    city varchar(255),
    street varchar(255),
    streetNumber varchar(255),
    country_id bigint,
    primary key (id, REV)
)

Is the REVTYPE an integer-based column? Try using the uppercase name as well.

If that does not fixes your issue, try to replicate it with this test case.


#3

I found the issue, the entity extends a class that has an @inheritance joined annotation, so it is writting the REVTYPE on the super class. Do you think I can change this?


#4

Why do you mix the entities with the Envers tables?

Envers has a very specific table structurethat you need to have in place in order for Envers to work.


#5

I believe what he is saying is his JPA entity is one that uses Joined inheritance and that means when Envers generates its table structure, it too has multiple audit tables at play for a single row.

In this case, the REVTYPE column is actually only mapped and maintained in the base table for the inheritance model and isn’t replicated to the sub-types, this is by design.

I would like to better understand why you think this needs to exist in both tables.

We added similar support for REVEND and REVEND_TSTMP when using the ValidityAuditStrategy in an inheritance entity mapping model mainly because those columns are typically used as part of a table partition configuration and so it made sense replicate those to allow for properly partitioned tables across an inheritance model.

I don’t see how REVTYPE needs such treatment, but perhaps you have a use case I haven’t considered?


#6

I don’t need the revtype to exist in two tables, but I am implementing envers in an existent structure that has this relationships. I have:

//This is the entity that I want to audit
@Audited(withModifiedFlag=true)
@Entity
public class PurchaseOrderLine extends MaterialMovementWithRedundantChildSoftDelete
@MappedSuperclass
public abstract class MaterialMovementWithRedundantChildSoftDelete extends MaterialMovement
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@Entity
@Inheritance(strategy= InheritanceType.JOINED)
public abstract class MaterialMovement

On MaterialMovement_ AUD revtype is writting 0,1,2
And on PurchaseOrderLine revtype is writting nulls


#7

I simply wanted to confirm as I found it strange that you had REVTYPE in the PurchaseOrderLine_AUD table.

Correct; that’s because the mapping that Envers generates to ORM for the audit tables doesn’t include that field so when the insert operations for PurchaseOrderLine_AUD happen, that column is simply ignored.

If you are ever curious what XML mappings get generated by Envers in situations like this, you can enable specific class logging and have it dump that to your console, which can be useful when debugging.

This is what you’d need for Log4J and Hibernate Envers 5.x:

log4j.logger.org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl=trace

#8

Great thanks.

So there is no way to writte the REVTYPE on the PurchaseOrderLine_AUD table having the above structure?


#9

No, there is no out-of-the-box way to do that.

Having said that, that does not mean we cannot introduce a way to accomplish this in a future improvement to Envers. I believe the more important questions to ask here are:

  1. Does it make sense and what value does it bring?
  2. What backward compatibility concerns does it raise?

I’ve already touched on my stance with it being a JOINED inheritance strategy mapping and why its simply mapped at the base table level rather than replicated to the sub-type tables.

As I said earlier, if you have a strong case that illustrates the relevance/importance/value of why it should be replicated, I’m open to hearing it. I also have to be concerned with backward compatibility and so if you have a reasonable case to warrant the change, it would be something that we’d need to keep disabled by default and allow users to opt-in as desired rather than it being the norm behavior.

One final thought, while Envers does not support this out-of-the-box – nothing technically stops you from using database specific features like a manual trigger to replicate the column from the base table to the sub-type table.


#10

Yes, I am doing this. Thank you for the answers