_MOD columns not named correctly when using custom column names

Description

My envers configuration is:

properties.setProperty(EnversSettings.AUDIT_TABLE_SUFFIX, "_history"); properties.setProperty(EnversSettings.AUDIT_STRATEGY, "org.hibernate.envers.strategy.ValidityAuditStrategy"); properties.setProperty(EnversSettings.GLOBAL_WITH_MODIFIED_FLAG, "true"); properties.setProperty(EnversSettings.MODIFIED_FLAG_SUFFIX, "_mod");

Now, I have the following entity:

@Audited @Entity(name = "orders") public final class Order { @ManyToOne @JoinColumn(name = "customer_account_id", nullable = false) private CustomerAccount customerAccount; // And many more ... (including an id, ...) }

Now, running hibernate creates the following tables:

1. A table `orders` is created with the column (among others)

  • 'customer_account_id'

2. A table `orders_history` is created with the following columns (among others)

  • `customer_account_id`

  • `customer_account_mod`.

But, I think, the name of second column, storing the modification flag, should be `customer_account_id_mod` instead.

So, I think, envers is ignoring the custom column name for the '_mod' fields defined by '@JoinColumn(name = "customer_account_id" ...).

Activity

Show:

Chris CranfordSeptember 18, 2019 at 3:36 AM

I’ve tentatively scheduled this for release in 5.4.6. There is an associated PR that can be reviewed. Unless I hear otherwise, I’ll likely push this to master by end of the week.

Chris CranfordSeptember 17, 2019 at 9:07 PM

For the point about ticks in column names, that will likely end up being a per-user concern. I’d rather focus on delivering fundamental strategy support for this and then if users have specific needs beyond what we support of the box, the tools are there for users to extend our strategies, supplement the behavior, and then supply that to Envers to get that altered behavior.

Chris CranfordSeptember 17, 2019 at 9:01 PM
Edited

I came across a problem today when trying to backport this into 5.4.

In the example provided in the issue description, the idea was there was a

@ManyToOne @JoinColumn(name = "some_other_id") private SomeObject object;

When the association’s foreign-key is a single column, there really isn’t much problem by implementing behavior to set the modified column name to be some_other_id_MOD, however when the foreign-key consists of multiple columns, then this raises the question of how should that modified flag column be represented.

Lets assume we have this mapping:

@ManyToOne @JoinColumns{ @JoinColumn(name = "column_id1"), @JoinColumn(name = "column_id2") }) private SomeObject object;

It makes no sense to me to add both a column_id1_MOD and column_id2_MOD column to the audit table mapping, because we aren’t concerned with whether part of the foreign-key changed but rather whether or not the associated entity as a whole changed.

Therefore I’m inclined to follow these rules for the improved strategy:

  • If property is a basic-type (single column valued attribute), use the modifiedColumnName attribute if supplied, otherwise use the resolved column name with the suffix appended.

  • If property is an association and the foreign-key association consists of a single-column, treat the resolution of the modified column as if its a basic-type (single column valued attribute); see above.

  • If property is an association and the foreign-key association consists of multiple columns, use the modifiedColumnName attribute if supplied, otherwise use the property name with the suffix appended.

  • If property is an embeddable, retain legacy behavior. In this case, use the modifiedColumnName attribute if supplied, otherwise use the embeddable property name with the suffix appended.

The last two are obviously less than ideal; however I believe that gives the most possible flexibility while not really changing the behavior all too drastically.

, I’ll open a separate issue on this as a follow-up as I don’t want to mix too many concerns.

Tuomas KiviahoDecember 15, 2017 at 10:39 AM

I also noticed that still the @Audited has to be declared on the property (both reader and writer just in case) when @Access(AccessType.PROPERTY) is use. Can this be laxed at the same time so that it'd fall back to the field just like the other annotations do.

Tuomas KiviahoDecember 15, 2017 at 10:29 AM

I've got MySQL ticks in @JoinColumn names due to historical reasons and I got me thinking that the removal of the possible quotation should also be taken care of when this is implemented.

Fixed

Details

Assignee

Reporter

Fix versions

Priority

Created December 21, 2015 at 5:38 PM
Updated January 14, 2020 at 12:14 AM
Resolved October 1, 2019 at 2:39 PM

Flag notifications