[英]How can I do a JPA @OneToMany unidirectional mapping with the parent entity's composite key?
當前,這些只是查詢操作,如果您“獲取”父級,則希望獲取所有子級。 它是遺留的遺留數據庫(DB2),其中父表中的三個字段是其組合PK。 子表具有這三個字段,另外一個作為其組合PK。
無需雙向。 只需要讓孩子和父母一起。
@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類非常類似於父類和另一個字段。
我需要切換到@Embeddable和@EmbeddableId等嗎? 無論如何,任何人都有如何使這項工作的想法? 我看過的例子更加簡單化,似乎對我不起作用。
我可以更改Parent和Child類,但不能更改表及其當前的組合PK。
您可以使用@IdClass
或@EmbeddedId
。 無論哪種方式,您都在使用“派生身份”。 這是使用@IdClass
的可能解決方案:
@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;
}
JPA 2.1規范的第2.4.1節中討論了派生身份。
您可以繼續使用@IdClass
進行單向映射 。 為此,您可以在Parent
類的List<Child> children
字段上添加@JoinColumns({...)}
以及cascade
屬性,如下所示:
@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;
}
但是,更好的主意是按照Brian的回答中的說明,使用帶有mappedBy
雙向映射 。
從執行的DML語句開始,它是有效的。 隨着Unidirectional
你會看到每一個額外的更新語句children
在實體 List<Child>
,同時節省了Parent
。 而且使用Bidirectional
時,不會導致此額外的更新語句。
更新:
我的測試代碼檢索:
session = openSession();
tx = session.beginTransaction();
System.out.println(session.createQuery("select p from Parent p").list());
tx.commit();
並給我以下
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 :** [org.hibernate.bugs.Parent@1e17ad20, org.hibernate.bugs.Parent@7111ca49]
使用以下DDL
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
因此,首先,這是Groovy,上面的代碼有點暗示,但我沒有明確提及。 這要求注釋使用方括號“ []”而不是大括號“ {}”來指定數組屬性,例如@JoinColumn。
除此之外,它比我想象的要簡單。 對於具有相同字段的單向關系,我不需要指定實際的列名或引用的列名。 只是常見的字段名稱。
我還切換到Set並按在數據庫中指定鍵的順序放置@JoinColumns。 最后兩件事可能並不重要。
@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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.