JPA @ManyToMany пишет при создании, но не обновлении - PullRequest
5 голосов
/ 04 июня 2009

У моей команды есть два класса, User и Store, связанные с аннотациями JPA @ManyToMany. Соответствующий код ниже.

При создании нового объекта User и настройке его хранилищ жизнь прекрасна. Но мы видим неожиданное поведение при попытке обновить объекты User через наш веб-интерфейс Struts 2 / Spring. (Эти проблемы не возникают при запуске простых автоматических интеграционных тестов через JUnit).

Проще говоря, при сохранении User его коллекция хранилищ не обновляется - база данных не показывает изменений, а перезагрузка рассматриваемого объекта User показывает, что он имеет неизменный набор хранилищ.

Единственное решение, которое мы нашли для этой проблемы - и нам не нравится это решение, оно заставляет всех разработчиков в нашей команде немного нервничать - это создать новый Set из Store s, затем выполните user.setStores(null), затем выполните user.setStores(stores).

Мы используем OpenEntityManagerInViewFilter; мы используем Hibernate в качестве нашего JPA-провайдера; мы используем Spring JpaTransactionManager. У нас нет @Transactional аннотаций в нашем коде - и их добавление нарушает существующий код из-за поведения прокси, описанного в другом месте.

Приветствуется любое понимание того, как мы могли бы решить эту проблему несложным способом.


Соответствующая часть User.java:

@ManyToMany
@JoinTable(name = "company.user_store_access",
        joinColumns = @JoinColumn(name = "userid"),
        inverseJoinColumns = @JoinColumn(name = "storeid"))
public Set<Store> getStores() {
    return stores;
}

Соответствующая часть Store.java:

  @ManyToMany(mappedBy = "stores")
    public List<User> getUsers() {
        return users;
    }

Соответствующие части UserDetailAction.java: (сквозные переходы на один или два слоя, а затем:)

entity = getEntityManager().merge(entity);

Ответы [ 3 ]

6 голосов
/ 21 января 2010

Проблема в том, что у вас двунаправленное отношение, и в этом случае есть одна сущность, которая контролирует другую, и из вашего сопоставления контролирующей является сущность Store , а не Пользователь , поэтому добавление пользователя в магазин будет работать (так как магазин - тот, кто контролирует), но добавление магазина пользователю не будет.

попробуйте перевернуть ситуацию, сделав объект User тем, кто контролирует отношение, поместив аннотацию @ManyToMany (mappedBy = "users") в метод getStores () и изменив getUsers ().

Надеюсь, это помогло.

P.S. сущность, которая контролирует отношение, всегда является той, у которой нет атрибута mappedBy.

2 голосов
/ 04 февраля 2010

Я просто застрял в той же проблеме и нашел решение на другой странице.

Вот что сработало для меня

вызов getJpaTemplate (). Flush () до того, как слияние сработало для меня.

Я не понял, почему это сработало.

1 голос
/ 04 июня 2009

Пожалуйста попробуйте следующую аннотацию в вашем объекте User:

@ManyToMany(cascade = {CascadeType.ALL})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...