2012-10-12 20 views
5

Mam dwa modele.Hibernacja (JPA) wiele @OneToMany dla tego samego modelu

@Entity 
public class Student 
{ 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    protected long id; 

    @? 
    protected Address homeAddress; 

    @? 
    protected Address schoolAddress; 
} 

@Entity 
public class Address 
{ 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    protected long id; 

    @? 
    protected List<Student> students; 
} 

Co WZP/hibernacji adnotacje muszę umieścić powyżej homeAddressschoolAddress i students, aby uczynić pracę stowarzyszenia?

Oczywiście próbowałem wielu rzeczy i nic nie działało. Na przykład, ustawienie

@ManyToOne 
    @JoinColumn (name="student_homeAddress_id", updatable = false, insertable = false) 
    protected Address homeAddress; 

    @ManyToOne 
    @JoinColumn (name="student_schoolAddress_id", updatable = false, insertable = false) 
    protected Address schoolAddress; 

i

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) 
    @JoinColumns({ 
    @JoinColumn(name = "student_homeAddress_id", referencedColumnName = "student_homeAddress_id"), 
    @JoinColumn(name = "student_schoolAddress_id", referencedColumnName = "student_schoolAddress_id")}) 
    @IndexColumn(name="students_index") 
    protected List<Student> students; 

yealds Unable to find column with logical name: student_homeAddress_id in org.hibernate.mapping.Table(Address) and its related supertables and secondary tables. próbował również przy użyciu mappedBy ale że przyjmuje jeden argument (nie można zrobić mappedBy="student_homeAddress_id, student_schoolAddress_id".

również wyglądał na przesuwanie JoinColumns do tabletu Student ale nie jestem pewien, co adnotacje powinny wyglądać dla OneToMany i ManyToOne jak mam wiele adresów, które JoinColumns tam nie ma sensu

rzecz, która nie działa, ale nie było stworzenie stowarzyszenia był o.

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER) 
    @JoinColumn(name="address_id") 
    @IndexColumn(name="students_index") 
    protected List<Student> students; 

Używanie tego, podczas przechowywania w DB modelach student_homeAddress_id i student_schoolAddress_id były zawsze puste, nawet po zapisaniu obu końców (model Studenta i Adresu).

Moja myśl jest taka, że ​​na stole Address będą 3 dodatkowe kolumny: student_homeAddress_id (identyfikator studenta w tabeli Studenta dla homeAddress) student_schoolAddress_id (identyfikator studenta w tabeli Studenta dla schoolAddress) i students_index (lokalizacja oparta na 0 na liście students). To powinno wystarczyć, prawda?

Wszelkie pomysły?

Wielkie dzięki!

Odpowiedz

3

Wypróbowaliśmy sugestię Maela, ale nie mogliśmy jej wykonać.

Skończyło się na tym, że zadziałało this.

Innymi słowy, mamy OneToMany relacje:

On Student:

protected List<AddressStudentAssociation> addresses; 

On Address:

protected List<AddressStudentAssociation> students; 

oraz na AddressStudentAssociation:

@ManyToOne 
@PrimaryKeyJoinColumn(name="STUDENTID", referencedColumnName="id") 
private Student student; 
@ManyToOne 
@PrimaryKeyJoinColumn(name="ADDRESSID", referencedColumnName="id") 
private Address address; 

plus argument, aby oddzielić jeden adres od drugiego (isHome).

Wreszcie wewnątrz Student mamy public Address getHomeAddress(), który przechodzi przez listę addresses i zwraca poprawny adres. Musieliśmy także grać z adnotacjami, aby to działało. Generalnie nie jest optymalna, ale działa i spędziliśmy zbyt wiele czasu, próbując sprawić, by wszystko działało. : |

4

Jeśli masz podmiot, do którego chcesz powiązać @OneToMany w więcej niż jednym polu, powinieneś użyć @JoinTable, aby Hibernate mógł wygenerować 2 tabele dla relacji.

Z @JoinTable javadoc:

sprzężenia tabela jest zwykle stosowany w odwzorowaniu wiele-do-wielu, jednokierunkowych jeden do wielu związków. Może być również używany do mapowania dwukierunkowych powiązań wiele do jednego/jeden do wielu, jednokierunkowych wiele relacji jeden do jednego i jeden do jednego (zarówno dwukierunkowy i jednokierunkowy).

Gdy stół dołączyć stosuje się mapowanie relacji z klasy do osadzenia na stronie posiadanie relacji, zawierający podmiot zamiast zabudowany klasa jest uważany właściciel relacji .

W przypadku braku adnotacji JoinTable obowiązują wartości domyślne elementów adnotacji .Zakłada się, że nazwa tabeli łączenia to nazwy tabel skojarzonych tabel podstawowych połączonych razem (po stronie z przodu) za pomocą podkreślenia.

Weźmy ten przykład:

@Entity 
@Indexed(index = "causa_penal") 
@Table(name = "causas_penales") 
public class CausaPenal implements Serializable { 



    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    @Column(name = "id") 
    @DocumentId 
    private Integer id; 

    @Version 
    @Column(name = "opt_lock") 
    private Integer version; 

    @ManyToMany(cascade = { CascadeType.ALL }) 
    @JoinTable(name = "causapenal_imputados") 
    @IndexedEmbedded(depth = 1) 
    private List<ParteMaterial> imputados; 

    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "causapenal_victimas") 
    @IndexedEmbedded(depth = 1) 
    private List<ParteMaterial> victimas; 

    //Getters and Setters 
} 

Jak widać, mam CausaPenal wskazując ParteMaterial dwukrotnie. Ale potrzebuję tych list niezależnie od siebie. Tak więc przy pomocy @JoinTable mówię Hibernate, że ta relacja musi być odwzorowana za pomocą 4 tabel: "causa_penal" dla jednostki CausaPenal, "causa_penal_imputados" dla relacji CausaPenal i pola imputados, które jest odwzorowane na ParteMaterial Entity i to samo dla ofiary i wreszcie tabela dla ParteMaterial Entity.

Powiązane problemy