'Increment @version when an entity is embedded in an @embeddable

I know there is a similar question listed here but in my own case, I don't have the dates across . Rather, I have an embedded class with an entity in it. I have the below entity definitions:

Person JPA Entity

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Person {
    @Id
    private int id;

    @CreatedDate
    private OffsetDateTime creationDate;

    @LastModifiedDate
    private OffsetDateTime updatedDate;

    @Version
    private Long version;

    @Embedded
    private ContactAddress contactAddress;
}

ContactAddress JPA Entity

@Embeddable
public class ContactAddress {
    private String notice;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "former_street_id")
    private Street formerStreet;

      @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "new_street_id")
    private Street newStreet;
}

Street JPA Entity

@Table(name = "p_street")
public class Street  {
    @Id
    private int id;

    private String line1;
    private String line2;
}

The Street JPA entity is a field of the ContactAddress class. When I update a ContactAddress instance, the version in the Person entity is incremented provided it is the 'notice' field of the ContactAddress that is changed. If however, I update any of the Street Object fields, the version is not incremented. The reason being that I am definitely missing how to notify the auditingEntityListner to raise an event on the updateDate field on the Person entity.

It appears, with me having the Street entity in the embedded ContactAddress, a disconnect has been created between the Person entity and the Street entity. Is there a way to fix this in JPA?



Solution 1:[1]

It works as expected becauyse when you modify Street, you are not modifying, only some entity in different table. Person (person table) itself is unchanged thus no increment in version.

When you modify ContactAddress, since it is a "part of Person" (literally a set of columns in person table - thus person), you are modifying row in person entry, therfore version is bumped up.

If you need to version to bumped up (I would rather not) you have to "touch" Person when you are modifying Street entity. I dont know if there is an auto way of doing it.

Keep in mind, that your intention is to potentially increment version of multiple person entries when you modify address as address might be used in multiple person entries.

Solution 2:[2]

If you want to ensure that the @Version field is increased then:

@PersistenceContext
private EntityManager em;

public void savePerson(Person p) {

    em.lock(p, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
}

This way the person's version field is always increased.

Note that the version field is increased by two if the Envers framework is aware of an change, e.g. when notice has been modified.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Antoniossss
Solution 2 Markus Pscheidt