Версия всех дочерних элементов увеличивается в OneToMany при объединении родительского объекта - PullRequest
1 голос
/ 03 августа 2011

У меня есть отношение OneToMany, определенное следующим образом:

@Entity
Parent extends BaseEntity {
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
    private List<Child> childList;
    // ...
}

@Entity
Child extends BaseEntity {
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "PARENT_ID")
    private Parent parent;
    // ...
}

Аннотация @Version определена в классе BaseEntity.Объекты преобразуются в DTO и изменяются клиентом.Теперь, когда клиент меняет один из дочерних элементов, родительский элемент и его дочерние элементы преобразуются обратно в сущности, а слияние выполняется путем выполнения em.merge (parent), версия дочерних элементов увеличивается на единицу!Я ожидал, что версия измененного потомка будет только увеличена.Сначала я подумал, что это из-за моего EntityCallbackListener, который перехватывает слияние с @PreUpdate.Но если я закомментирую метод обратного вызова, поля версии других дочерних элементов все еще будут увеличены.У кого-нибудь есть объяснение этому поведению?

Я использую OpenJPA 1.2.3.


Хорошо, RTFM иногда помогает ...: - /

По умолчанию OpenJPA увеличивает версию для всех дочерних элементов:

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

Это значение по умолчанию openjpa.LockManager в JPA.

Этот параметр можно переопределить с помощью диспетчера пессимистической блокировки и его свойств.:

Пессимистичный LockManager может быть сконфигурирован для дополнительного выполнения проверки версии и приращения поведения менеджера блокировки версий, описанного ниже, путем установки его свойств VersionCheckOnReadLock и VersionUpdateOnWriteLock.

ИтакЯ настроил OpenJPA, чтобы не изменять версию при обновлении:

<property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=false)"/>

Но это не работает.Поля версий всех дочерних элементов все еще увеличиваются.Я что-то пропустил?Что мне нужно настроить, чтобы OpenJPA обновлял только поле версии измененных сущностей?

1 Ответ

1 голос
/ 02 сентября 2011

Проблема заключалась в неправильной реализации equals () и hashcode (), поэтому EntityManager предполагал, что все объекты в списке были изменены.

...