spark82
spark82

Reputation: 33

Hibernate cascade all and envers audit

I am looking for a solution, and I can't figure it out. Our project is structured like this (an example) :

module 1 :

    @Audited
    public class Person {
        int id;
        String firstName;
        String lastName;

        @JoinColumn(name = "car_id", referencedColumnName = "id", nullable = false)
        @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        List<Car> cars;
    }

    @Audited
    public class Car {
        String model;
        @ManyToOne(fetch = FetchType.LAZY)
        Person person;
    }

What we want to do is separate the entities and services linked in different modules. For example :
Person module

Car module

We want to keep the Cascade on the entity. But we do not want to have cyclic dependency. We remove the link From Car to Person

    @Audited
    public class Person {
        int id;
        String firstName;
        String lastName;

        @JoinColumn(name = "car_id", referencedColumnName = "id", nullable = false)
        @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        List<Car> cars;
    }

    @Audited
    public class Car {
        String model;
    }

My problem is when I update a car, no record is created for my Person, but I want one. Is it possible ?

Upvotes: 1

Views: 532

Answers (1)

Naros
Naros

Reputation: 21103

What we want to do is separate the entities and services linked in different modules.

Reality is your solution isn't technically doing that, the association between the two entities still exists. In the former mapping, both sides owned the association where-as in the latter its solely owned by Person.

Whenever you want to decouple entity models like this, its generally a more accepted practice to have some form of a proxy entity in one module that is meant to link to or provide basic information about the real entity that lives elsewhere, in your case another module.

In other words:

Person Module

  • Person entity
  • Car entity (proxy model)

Car Module

  • Car entity
  • Potentially a Person entity (proxy model)

The idea is then to use something like Debezium or some other trigger/hook to notify other modules when the real entity has changed so that its proxy model can reflect the changes. This would then allow you to get a full view of the audit model from within a single module rather than trying to obtain this across multiple modules effectively nullifying your goal of separation in the first place.

The reason these "proxy" models are important is that it allows one module's entity model to change over time with little to no impact to that of the adjacent modules that likely need only a subset of the original data.

The other alternative is to take a step back and realize that perhaps you're trying to split your data into modules in such a way that doesn't fit with your object model and relationships and therefore what you had is acceptable given the circumstances and relationships that exist in the entity model in the first place.

My problem is when I update a car, no record is created for my Person, but I want one. Is it possible ?

In your second mapping model, no it isn't possible. The reason for this is that the relationship is only owned by the Person entity in this case and the audit model for Car has no idea that it has any association at all with that of Person because there is no inverse (non-owning) mapping in the model.

With such an entity mapping, the only way this would work would be that when modifying a Person some attribute on the Car model would need to be changed so that it would trigger an audit entry for that entity. Naturally doing that contradicts the entire process of separating these in the first place, hence by comment regarding the alternative to accept these need to co-exist together.

Upvotes: 1

Related Questions