2016-12-14 2 views
0

Wir haben die folgende Entitätshierarchie und ein EntityListenerEnvers - fügen Sie neue Element zu OneToMany Sammlung in EntityListener @PreUpdate

@Entity 
@EntityListeners(value = DummyListener.class) 
@Audited 
public class A { 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a", fetch = FetchType.LAZY, orphanRemoval = true) 
    @Fetch(FetchMode.SELECT) 
    private Set<B> bs = new LinkedHashSet<B>(0); 
} 

@Entity 
@Audited 
public class B { 
    @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, CascadeType.PERSIST }) 
    @JoinColumn(name = "a_id", nullable = false) 
    private A a; 
} 

public class DummyListener { 
    @PreUpdate 
    public void beforeUpdate(A entity) { 
    entity.set...(...); 

    ... 

    B old = entity.getBs().iterator().next(); 
    old.set...(...); 

    ... 

    B b = new B(); 
    b.setA(entity); 

    entity.getBs().add(b); 
    ... 
    } 

}

In der Entität Zuhörer möchten wir neue B Einheit der hinzufügen Eine Entitätssammlung. Nach dem Speichern von A haben die Envers keinen Prüfsatz für die neue B-Instanz in der B-Prüftabelle erstellt. Alle anderen Änderungen haben Audit-Datensätze mit Ausnahme der neuen B-Instanz.

Was machen wir falsch? Es ist möglich, auf diese Weise eine neue Instanz von B zu erstellen?

Antwort

1

Per JPA Spec 2.1:

Im Allgemeinen ist die Lebensdauer Verfahren einer tragbaren Anwendung sollte nicht EntityManager oder Abfrageoperationen, Zugriff auf andere Objektinstanzen, oder ändern Beziehungen innerhalb der gleichen Persistenzkontext aufrufen.

Der Punkt hier ist, dass eine neue B durch Hinzufügen und beziehen es zu A bedeutet sind Sie die Beziehungen zwischen den Entitäten ändern, wenn auch eine neue Einheit B.

den folgenden Code So nehmen:

@PreUpdate 
public void onPreUpdate(Object object) { 
    if (object instanceof A) { 
    final A a = (A) object; 
    final B b = new B(); 
    b.setA(a); 
    a.getBs().add(b); 
    } 
} 

Wenn Sie diesen Test mit Hibernate einfach und keine Revision, würden Sie feststellen, dass die neue Instanz von B nicht einmal seine beibehalten, wenn sie innerhalb des Lebenszyklus Callback erstellt von @PreUpdate.

Wenn Hibernate einen solchen Anwendungsfall nicht zulässt, gibt es keine Möglichkeit, Envers überhaupt in der Lage zu sein, Zustandsänderungen zu erkennen und die erforderlichen Erfassungsarbeitseinheiten auszuführen.

+0

Danke für die Antwort! Ich fount auch die Antwort in der JPA-Dokumentation, also sollten wir eine andere Möglichkeit finden, eine trigger-ähnliche Methode zu erstellen, oder die Logik in eine andere serverseitige Implementierung zu verschieben. – SeniorRoland

Verwandte Themen