2009-06-03 22 views
5

Mój zespół ma dwie klasy: User i Store, powiązane z adnotacjami JPA @ManyToMany. Odpowiedni kod znajduje się poniżej.JPA @ManyToMany Pisanie w trakcie tworzenia, ale nieaktualizacja

Podczas tworzenia nowego obiektu User i ustawiania jego sklepów, życie jest dobre. Obserwujemy jednak nieoczekiwane zachowanie podczas próby aktualizacji obiektów użytkownika za pośrednictwem naszego interfejsu internetowego Struts 2/Spring. (Problemy te nie występują podczas uruchamiania prostych zautomatyzowanych testów integracyjnych za pośrednictwem JUnit).

Po prostu, zapisując kolekcję User, jej kolekcja sklepów nie jest aktualizowana - baza danych nie wyświetla żadnych zmian, a przeładowania wymienionego obiektu User pokazują, że ma on niezmieniony zbiór sklepów.

Jedynym rozwiązaniem, które znaleźliśmy w tym problemie - i nie podoba nam się to rozwiązanie, sprawia, że ​​wszyscy programiści w naszym zespole są nieco mdlący - jest stworzenie nowego Set z Store s, a następnie wykonaj user.setStores(null), a następnie wykonaj user.setStores(stores).

Używamy OpenEntityManagerInViewFilter; używamy Hibernate jako naszego dostawcy JPA; używamy Spring'a JpaTransactionManager. Nie mamy adnotacji @Transactional w naszym kodzie - i dodanie ich powoduje przerwanie istniejącego kodu z powodu zachowania proxy opisanego gdzie indziej.

Każdy wgląd, jaki ktoś może przekazać, abyśmy mogli rozwiązać ten problem w niezawodny sposób, jest mile widziany.


odpowiedniej części User.java:

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

odpowiedniej części Store.java:

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

Odpowiednie części UserDetailAction.java: (przechodzą przepusty dół warstwy lub dwa, a następnie :)

entity = getEntityManager().merge(entity); 
+1

Czy możesz dodać linie kodu, w których dodajesz/modyfikujesz Sklepy? –

Odpowiedz

1

Spróbuj następującą adnotację w obiekcie użytkownika:

@ManyToMany(cascade = {CascadeType.ALL}) 
+0

Dam ci spróbować rano - chociaż dodaliśmy już @ManyToMany (cascade = {CascadeType.PERSIST, CascadeType.MERGE}) już. –

6

Problemem jest to, że posiada dwukierunkową relację, aw tym przypadku jest jeden podmiot, który kontroluje drugą, iz mapowanie Kontrolujący Jednym z nich jest encja Store, a zatem użytkownik dodający użytkownika do sklepu będzie działał (ponieważ to on kontroluje), ale dodanie sklepu do użytkownika nie będzie możliwe.

spróbuj odwrócić sytuację, zmieniając obiekt użytkownika w osobę, która kontroluje relację, umieszczając adnotację @ManyToMany (mappedBy = "users") w metodzie getStores() i zmieniając metodę getUsers().

Mam nadzieję, że pomogło.

P.S. podmiotem, który kontroluje relację, jest zawsze ten, który nie ma atrybutu mapowanegoBy.

2

Po prostu utknąłem w tym samym problemie i znalazłem rozwiązanie na innej stronie.

Oto co pracował dla mnie

nazywając getJpaTemplate(). Flush() przed wywołaniem seryjnej pracował dla mnie.

Nie dostałem powodu, dla którego zadziałało.