2016-12-14 6 views
0

Мы имеем следующую иерархию сущность и EntityListenerEnvers - добавить новый элемент в коллекции oneToMany в 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); 
    ... 
    } 

}

В сущности слушателю мы хотели бы, чтобы добавить новый B объект в Коллекция сущностей. Но после сохранения A пользователи не создали запись аудита для нового экземпляра B в таблице аудита B. Все остальные изменения содержат записи аудита, кроме нового экземпляра B.

Что мы не так? Таким образом можно создать новый экземпляр B?

ответ

1

Per JPA Spec 2.1:

В целом, метод Жизненный цикл портативного приложения не должны ссылаться на EntityManager или запроса операции, доступ к другим экземплярам сущности, или изменить отношения в том же контексте, настойчивость.

Дело в том, что при добавлении нового B и связывая его с A означает, что вы изменения отношений между сущностями, хотя новый субъект B.

Так что, следующий код:

@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); 
    } 
} 

Если проверить это только с Hibernate и не аудит, вы бы заметить, что новый экземпляр B даже не сохраняется, когда его создали в жизненном цикле обратного вызова @PreUpdate.

Так что если Hibernate не разрешает такой вариант использования, нет способа, который Envers мог бы даже обнаруживать изменения состояния и выполнять необходимые единицы работы коллекции.

+0

Спасибо за ответ! Я также объясняю ответ в документе JPA, поэтому мы должны найти другой способ создания триггерного метода или переместить логику в другую систему на стороне сервера. – SeniorRoland

Смежные вопросы