2015-08-14 27 views
5

Mam kilka adnotacji Hibernate/JPA (nadal nie wiem różnicy, aby być szczerym), które pozwalają mi utworzyć klasę asocjacyjną. Ta klasa łączy dwa elementy powiązane z jednym obiektem. Pierwotnie używałem @JoinTable, ale zdałem sobie sprawę, że potrzebuję dużo więcej metadanych ze skojarzeniami, więc musiałem przekonwertować kod na inny typ obiektu.Hibernate @ManyToOne Referencje klasy przy użyciu @NaturalId zamiast @Id

Na razie używam @Id zaznaczyć kolumnę ID dla moich przedmiotów, a przy użyciu @NaturalId (mutable = false) dla String uuid.

Moja klasa asocjacji używa @ManyToOne i tworzy tabelę dobrze, ale gdy się jej przyglądam, tabela używa pola @Id jako kolumny odwzorowania. Wolałbym, aby ta klasa asocjacji korzystała z @NaturalId uuid, aby ułatwić przenoszenie relacji/skojarzeń do innych systemów.

Jak mogę uzyskać poprawność identyfikatora?

Dla porównania, mój wygląd kodu Java DB i tak:

AssociationsTable 
---------------------------------------------- 
| ID | META DATA | ID ASSOC. 1 | ID ASSOC. 2 | 
---------------------------------------------- 
| 1 | stuff | 1  |  2  | 
---------------------------------------------- 

Objects 
------------------------------ 
| ID | META DATA | UUID  | 
------------------------------ 
| 1 | stuff | FOO-123 | 
------------------------------ 
| 2 | stuff | BAR-456 | 
------------------------------ 

Association Class{ 
    ObjA main; 
    ObjA sub; 

    @ManyToOne 
    getMain() 

    @ManyToOne 
    getSub() 
} 

ObjA Class{ 
    Long id; 
    @Id 
    @GeneratedValue(generator="increment") 
    @GenericGenerator(name="increment", strategy = "increment") 
    @XmlElement 
    @Column(name = "ID", unique = true, nullable = false) 
    getId() 

    String uuid;  
    @NaturalId (mutable = false) 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    @Column(name = "uuid", unique = true) 
    getUUID() 
} 
+0

Zdaję sobie sprawę z [twojego poprzedniego pytania] (http://stackoverflow.com/q/31926396/835000). Postanowiłem więc wyjaśnić: dlaczego martwisz się połączeniem tabel? Mam na myśli podmioty na poziomie bazy danych mogą być połączone z '@ Id', następnie mogą być serializowane z resetowanymi wartościami kluczy, następnie przesyłane do innych instancji, przekształcane do postaci szeregowej ze wszystkimi relacjami na poziomie Java-bean, a następnie przepuszczane w nowej bazie danych z nowymi wartościami dla Właściwości '@ Id' ... Klucze podstawowe dla jednostek będą różne, ale nadal będziesz je otrzymywać za pomocą pola' @ NaturalId'. Czy coś pominąłem? .. – svaor

Odpowiedz

3

Można użyć atrybutu @JoinColumnreferencedColumnName, jak wspomniano here. Tak dla przykładu, odwzorowania powinna być następująca:

ObjA.java:

package hello; 

import org.hibernate.annotations.NaturalId; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 

@Entity 
public class ObjA { 
    Long id; 
    String uuid; 

    public ObjA() { 
    } 

    public ObjA(String uuid) { 
     this.uuid = uuid; 
    } 

    @Id 
    @GeneratedValue 
    @Column(name = "obj_a_id", unique = true, nullable = false) 
    Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @NaturalId(mutable = false) 
    @Column(name = "uuid", unique = true, nullable = false) 
    public String getUuid() { 
     return uuid; 
    } 

    public void setUuid(String uuid) { 
     this.uuid = uuid; 
    } 
} 

Association.java:

package hello; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 

@Entity 
public class Association { 
    Long id; 
    ObjA main; 
    ObjA sub; 

    public Association() { 
    } 

    public Association(ObjA main, ObjA sub) { 
     this.main = main; 
     this.sub = sub; 
    } 

    @Id 
    @GeneratedValue 
    @Column(name = "association_id", unique = true, nullable = false) 
    Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @ManyToOne 
    @JoinColumn(name = "main_uuid", referencedColumnName = "uuid", nullable = false) 
    public ObjA getMain() { 
     return main; 
    } 

    public void setMain(ObjA main) { 
     this.main = main; 
    } 

    @ManyToOne 
    @JoinColumn(name = "sub_uuid", referencedColumnName = "uuid", nullable = false) 
    public ObjA getSub() { 
     return sub; 
    } 

    public void setSub(ObjA sub) { 
     this.sub = sub; 
    } 
} 

Te mapowania pomyślnie przetestowany do przechowywania wartości z kolumny uuid tabeli obja w kolumnach main_uuid i sub_uuid z association tabela. Zostało to przetestowane przy użyciu org.hibernate.common:hibernate-commons-annotations:4.0.5.Final, org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final, org.hibernate:hibernate-core:4.3.10.Final i org.hibernate:hibernate-entitymanager:4.3.10.Final przeciwko PostgreSQL 9.4.4.

+1

Próbowałem tego, jak również przy użyciu 'refercedTable' w dodatku, bez powodzenia. – Walls

+1

@Walls Właśnie próbowałem używać 'referencedColumnName' na moim lokalnym komputerze i to działało dla mnie. Zaktualizowałem swoją odpowiedź z użyciem dokładnie odwzorowanych mapowań. Jeśli nie widzisz identyfikatorów UUID w tabeli powiązań, upewnij się, że wskazujesz odpowiednią bazę danych i że ją również regenerujesz. – heenenee

Powiązane problemy