2016-04-01 28 views
0

Şimdilik bunlar yalnızca ebeveynleri "alırsanız", tüm çocukları almaya hevesli olmak istediğiniz yalnızca sorgulama işlemleridir. Ebeveyn tablosunda bileşik PK olan üç alanın bulunduğu eski bir eski veritabanı (DB2) var. Çocuk masasında bu üç alan ve bir tane daha bileşik PK vardır.Ana varlığın bileşik anahtarı ile JPA @ OneToMany tek yönlü eşleştirmeyi nasıl yapabilirim?

İki yönlü gerek yoktur. Sadece çocukları ebeveynle birlikte almalıyız.

@Entity @IdClass(ParentId.class) 
class Parent { 
    @Id int someId 
    @Id int someCode 
    @Id Date someDate 

    @OneToMany(fetch = FetchType.EAGER, ???) 
    ??? 
    List<Child> children 
} 

class ParentId implements Serializable { 
    int someId 
    int someCode 
    Date someDate 
} 

@Entity @IdClass(ChildId.class) 
class Child { 
    @Id int someId 
    @Id int someCode 
    @Id Date someDate 
    @Id String childValue 
    ... 
} 

class ChildId implements Serializable { 
    int someId 
    int someCode 
    Date someDate 
    String childValue 
} 

ChildId sınıfı, bir diğeri artı bir başka alana benziyor.

@Embeddable ve @EmbeddableId vb. Geçiş yapmam gerekir mi? Ne olursa olsun, bu işin nasıl yapılacağı konusunda fikir sahibi olan var mı? Daha basit olan ve benim için işe yaramayan örnekler gördüm.

Ebeveyn ve Çocuk sınıflarını değiştirebilirim, ancak tabloları ve mevcut bileşik PK'lerini değiştiremiyorum.

cevap

0

Her şeyden önce, bu, yukarıdaki kodun kastedildiği Groovy'dur fakat açık bir şekilde bahsetmedim. Bu, ek açıklamaların, @JoinColumn gibi dizi özelliklerini belirtmek için '{}' küme parantezleri yerine '[]' parantez kullanmasını gerektirir. Bunun ötesinde düşündüğümden daha basitti.Aynı alanlarla tek yönlü ilişki için, gerçek sütun adlarını veya başvurulan sütun adlarını belirtmem gerekli değildi. Sadece ortak olan alan adları.

Ayrıca bir Set'e geçtim ve @JoinColumns anahtarlarını veritabanında belirtildikleri sıraya yerleştirdim. Bu son iki şey muhtemelen önemli değil.

@Entity @IdClass(ParentId.class) 
class Parent { 
    @Id int someCode 
    @Id Date someDate 
    @Id int someId 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumns([@JoinColumn(name = "someCode"), 
     @JoinColumn(name = "someDate"), 
     @JoinColumn(name = "someId")]) 
    Set<Child> children 
} 
1

@IdClass veya @EmbeddedId'u kullanabilirsiniz. Her iki şekilde de "Türetilmiş kimlikler" kullanıyorsunuz.

@Entity 
@IdClass(ParentId.class) 
public class Parent { 
    @Id int someId; 
    @Id int someCode; 
    @Id Date someDate; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "parent") 
    List<Child> children; 
} 

public class ParentId implements Serializable { 
    int someId; 
    int someCode; 
    Date someDate; 
    ... 
} 

@Entity 
@IdClass(ChildId.class) 
public class Child { 
    @Id 
    @ManyToOne 
    @JoinColumns({ 
     @JoinColumn(name="PARENT_ID", referencedColumnName="someId"), 
     @JoinColumn(name="PARENT_CODE", referencedColumnName="someCode"), 
     @JoinColumn(name="PARENT_DATE", referencedColumnName="someDate") 
    }) 
    Parent parent; 
    @Id String childValue; 
    ... 
} 

public class ChildId implements Serializable { 
    ParentId parent; // matches name of attribute and type of Parent Id class 
    String childValue; 
} 

Türetilmiş kimlikler JPA 2.1 spec tartışılmaktadır, bölüm 2.4.1: Burada @IdClass kullanarak olası bir çözümdür.

+0

Teşekkürler, Bu ASAP'ı deneyeceğim. –

1

@IdClassTek Yönlü eşleme ile devam edebilirsiniz.

@Entity @IdClass(ParentId.class) 
class Parent { 
    @Id int someId; 
    @Id int someCode; 
    @Id Date someDate; 

    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL) 
    @JoinColumns({ 
     @JoinColumn(name="someId", referencedColumnName="someId"), 
     @JoinColumn(name="someCode", referencedColumnName="someCode"), 
     @JoinColumn(name="someDate", referencedColumnName="someDate") 
})  
    List<CKChild> children = new ArrayList<>(); 
} 
class ParentId implements Serializable { 
    int someId; 
    int someCode; 
    Date someDate; 
} 

@Entity @IdClass(ChildId.class) 
class Child { 
    @Id int someId; 
    @Id int someCode; 
    @Id Date someDate; 
    @Id String childValue; 
} 

class ChildId implements Serializable { 
    int someId; 
    int someCode; 
    Date someDate; 
    String childValue; 
} 

Ama sonra, daha iyi bir fikir belirtildiği gibi mappedBy ile bidirection haritalama ile gitmek olurdu: Bunun için aşağıda, Parent sınıfına List<Child> children sahada cascade özniteliği ile @JoinColumns({...)} boyunca ekleyebilir Brian'ın cevabı.

Yürütülecek DML deyiminden etkilidir. Unidirectional ilenumaralı numaralı numaralı her tek bir güncelleme bildirimini görürsünüz ve Parent kaydedebilirsiniz. Ve Bidirectional ile bu ek güncelleme bildirimi ile sonuçlanmaz.

GÜNCELLEME:

Testim kodu almak için: me aşağıdaki DDLS ile

Hibernate: select ckparent0_.someCode as someCode1_1_, ckparent0_.someDate as someDate2_1_, ckparent0_.someId as someId3_1_ from Parent ckparent0_ 
Hibernate: select children0_.someCode as someCode2_0_0_, children0_.someDate as someDate3_0_0_, children0_.someId as someId4_0_0_, children0_.childValue as childVal1_0_0_, children0_.childValue as childVal1_0_1_, children0_.someCode as someCode2_0_1_, children0_.someDate as someDate3_0_1_, children0_.someId as someId4_0_1_ from Child children0_ where children0_.someCode=? and children0_.someDate=? and children0_.someId=? 
Hibernate: select children0_.someCode as someCode2_0_0_, children0_.someDate as someDate3_0_0_, children0_.someId as someId4_0_0_, children0_.childValue as childVal1_0_0_, children0_.childValue as childVal1_0_1_, children0_.someCode as someCode2_0_1_, children0_.someDate as someDate3_0_1_, children0_.someId as someId4_0_1_ from Child children0_ where children0_.someCode=? and children0_.someDate=? and children0_.someId=? 
**Retrieved :** [[email protected], [email protected]] 

aşağıdaki

session = openSession(); 
tx = session.beginTransaction(); 
System.out.println(session.createQuery("select p from Parent p").list()); 
tx.commit(); 

ve verir

Hibernate: create table Child (childValue varchar(255) not null, someCode integer not null, someDate timestamp not null, someId integer not null, primary key (childValue, someCode, someDate, someId)) 
Hibernate: create table Parent (someCode integer not null, someDate timestamp not null, someId integer not null, primary key (someCode, someDate, someId)) 
Hibernate: alter table Child add constraint FKl06s6kkl5xx2s82tlbsh160vo foreign key (someCode, someDate, someId) references Parent 
+0

Tamam, bunu ASAP da deneyeceğim. Teşekkürler! –

+0

Yine de bunu işe alamıyorum. Bu hafta biraz daha deneyeceğim. DB2 lehçesi ile ilgili bir sorun olabilir. –

+0

@ToddWCrone H2 db ile test ettim ve kayıtları düzgün şekilde devam ettirebildim. Kodumu güncelledeyim ve küçük bir değişiklik yaptım. 'List çocuk = yeni ArrayList <>(); 'yerine' çocuklar listesi; 'bcos Ben bunu yapmak istemedim mantığı devam ettir. Ayrıca bu iki tablo için SQL DDL ekleyerek yardımcı olur. –