[英]JPA 2 Hibernate mapping with composite key in primary key using @IdClass with 3 tier structure
這個問題非常類似於: JPA(Hibernate,EclipseLink)映射:為什么這段代碼不起作用(使用JPA 2.0,@ EmbeddedId復合PK-FK的2個關系鏈)?
實際上我的唯一(從我發現的有意義的)差異是我使用@IdClass
並且我很可能無法切換到與hibernate不同的提供者。
但無論如何這里是代碼(刪除不重要的部分):
PermissionContextType.java
:
@Entity
@IdClass(PermissionContextTypePk.class)
public class PermissionContextType{
@Id
private String id;
@Id
@JoinColumn (name = "PROJECT", referencedColumnName = "ID")
@ManyToOne ()
private Project project;
public static class PermissionContextTypePk implements Serializable{
public String project;
public String id;
// ... eq and hashCode here ...
}
}
PermissionContext.java
:
@Entity
@IdClass(PermissionContextPk.class)
public class PermissionContext{
@Id
private String id;
@Id
@JoinColumns ({
@JoinColumn (name = "PROJECT", referencedColumnName = "PROJECT"),
@JoinColumn (name = "PERMISSIONCONTEXTTYPE", referencedColumnName = "ID")
})
@ManyToOne
private PermissionContextType permissionContextType;
public static class PermissionContextPk implements Serializable{
public String id;
public PermissionContextTypePk permissionContextType;
// ... eq and hashCode here ...
}
}
Permission.java
:
@Entity
@IdClass(PermissionPk.class)
public class Permission{
@Id
private String id;
@Id
@JoinColumns ({
@JoinColumn (name = "PROJECT", referencedColumnName = "PROJECT"),
@JoinColumn (name = "PERMISSIONCONTEXTTYPE", referencedColumnName = "PERMISSIONCONTEXTTYPE"),
@JoinColumn (name = "PERMISSIONCONTEXT", referencedColumnName = "ID")
})
@ManyToOne
private PermissionContext permissionContext;
public static class PermissionPk implements Serializable{
public String id;
public PermissionContextPk permissionContext;
// ... eq and hashCode here ...
}
}
而我得到的是:
org.hibernate.AssertionFailure: Unexpected nested component on the referenced entity when mapping a @MapsId: PermissionContext
Caused by: org.hibernate.AssertionFailure: org.hibernate.AssertionFailure: Unexpected nested component on the referenced entity when mapping a @MapsId: PermissionContext
有沒有人知道這是一個hibernate錯誤,我應該將它發布在他們的問題跟蹤系統上(並祈禱我能夠更新到給定的hibernate版本)或者我的綁定實體的方式是否存在根本錯誤?
我已經使用EAP 6.1(4.2.0)上的hibernate實現以及wildfly(不知道哪一個)進行了檢查。
好的,所以這是我到目前為止所發現的:
謝謝我的朋友: https : //hibernate.atlassian.net/browse/HHH-5764這很可能就是這種行為的原因。
我發現了一個解決方法:
Permission.java:
@Entity
@IdClass(PermissionPk.class)
public class Permission{
@Id
private String id;
// for the next 3 fields there are no public acessors, so the public API of the class was not changed !
@Id
@Column(name = "PROJECT")
private String projectId;
@Id
@Column(name = "PERMISSIONCONTEXTTYPE")
private String permissionContextTypeId;
@Id
@Column(name = "PERMISSIONCONTEXT")
private String permissionContextId;
@JoinColumns ({
@JoinColumn (name = "PROJECT", referencedColumnName = "PROJECT", updatable = false, insertable = false),
@JoinColumn (name = "PERMISSIONCONTEXTTYPE", referencedColumnName = "PERMISSIONCONTEXTTYPE", updatable = false, insertable = false),
@JoinColumn (name = "PERMISSIONCONTEXT", referencedColumnName = "ID", updatable = false, insertable = false)
})
@ManyToOne
private PermissionContext permissionContext;
public static class PermissionPk implements Serializable{
// previously they where private as well, but removed public constructor for the sake of simplicity of the question - so no changes where necesary in public API of the class !
private String id;
private String projectId;
private String permissionContextTypeId;
private String permissionContextId;
public PermissionPk () {}
public PermissionPk (String aId, PermissionContextPk aPermissionContext) {
this.id = aId;
permissionContextId = aPermissionContext.id;
permissionContextTypeId = aPermissionContext.permissionContextType.id;
projectId = aPermissionContext.permissionContextType.project;
}
... eq and hashCode here ...
}
}
這個解決方法的好處是它不會以任何方式更改類的公共API(唯一的變化是我需要在Pk的上下文中創建字段,並且上下文類型對PermissionPk可見 - 它們之前是私有的,只有一個公共構造函數[但同樣簡化了問題]),也沒有改變jpql查詢,同時解決方法是可擴展的(任何層數 - 只要每個偶數pk不包含另一個pk),所以如果將解決錯誤,將很容易刪除變通方法。
我仍然樂意接受對我的解決方法或問題本身的任何評論。
今天我找到了另一種解決方法:)你可以完全省略@IdClass並使用hibernate特定的能力來動態創建復合鍵,因為它顯然不受此bug的影響。 這里的缺點是:
但是,如果你可以使用除休眠之外的任何東西,你也可以使用沒有這個bug的東西 - 所以可能1真的不是問題。 並且你可能不需要為這個實體提供em.find(或者可以通過session或jpql查詢來創建它)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.