我有以下設計:的EclipseLink:多列,一個對一,JPA 2.0使用@MapsId失敗,只讀上@JoinColumn(比較衍生身份)@EmbeddedId
Valid XHTML http://kawoolutions.com/media/nontransmuc-onetoone.png
簡單的邏輯:Foos使用相同的列(相同的鍵)使用多列PK來PostAddresses。
這裏是JPA 2.0 @EmbeddedId映射(使用FooId嵌套ID類PostAddressId和Foo中的@MapsId註釋映射到它):
@Entity
@Table(name = "PostAddresses")
public class PostAddress implements Serializable
{
@EmbeddedId
private PostAddressId embeddedId;
...
}
@Embeddable
public class PostAddressId implements Serializable
{
@Column(name = "contact_id")
private Integer contactId;
@Column(name = "ordinal_nbr")
private Integer ordinalNbr = 1;
...
}
@Entity
@Table(name = "Foos")
public class Foo implements Serializable
{
@EmbeddedId
private FooId embeddedId;
@MapsId(value = "postAddressId")
@OneToOne
@JoinColumns(value = {
@JoinColumn(name = "contact_id", referencedColumnName = "contact_id", insertable = false, updatable = false),
@JoinColumn(name = "ordinal_nbr", referencedColumnName = "ordinal_nbr", insertable = false, updatable = false)
})
private PostAddress postAddress;
...
}
@Embeddable
public class FooId implements Serializable
{
@Embedded
private PostAddressId postAddressId;
...
}
堆棧跟蹤:
Exception [EclipseLink-46] (Eclipse Persistence Services - 2.3.0.v20110429-r9282): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [Foos.ordinal_nbr].
Descriptor: RelationalDescriptor(tld.transmuc.model.Foo --> [DatabaseTable(Foos)])
Runtime Exceptions:
---------------------------------------------------------
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:535)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:476)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:435)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:673)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:618)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:206)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:460)
... 4 more
對我來說,映射是正確的。我檢查了幾次。請注意,在FooId中使用@Embedded註釋或不在EL中沒有區別。
請注意Foo.postAddress關係的@JoinColumn註釋,它們都是用insertable = false,updatable = false來定義的,以指示嵌入ID屬性爲可寫屬性。
請注意,我不是在尋找一個可行的解決方案,我可以簡單地刪除只讀insertable = false,updatable = false stuff。但問題是爲什麼上述映射在EclipseLink中失敗。 Hibernate有沒有問題與代碼。此外,以下,功能上等同代碼 - 這工作沒有問題在EL - 使用JPA 2.0 @IdClass派生身份樣子:
@Entity
@Table(name = "PostAddresses")
@IdClass(value = PostAddressId.class)
public class PostAddress implements Serializable
{
@Id
@Column(name = "contact_id")
private Integer contactId;
@Id
@Column(name = "ordinal_nbr")
private Integer ordinalNbr = 1;
...
}
public class PostAddressId implements Serializable
{
private Integer contactId;
private Integer ordinalNbr = 1;
...
}
@Entity
@Table(name = "Foos")
@IdClass(value = FooId.class)
public class Foo implements Serializable
{
@Id
@OneToOne
@JoinColumns(value = {
@JoinColumn(name = "contact_id", referencedColumnName = "contact_id", insertable = false, updatable = false),
@JoinColumn(name = "ordinal_nbr", referencedColumnName = "ordinal_nbr", insertable = false, updatable = false)
})
private PostAddress postAddress;
...
}
public class FooId implements Serializable
{
private PostAddressId postAddress;
...
}
正如你所看到的,Foo.postAddress還設有讀僅限於insertable = false,updatable = false屬性。通過將Foo.postAddress命名爲相同,Foo.postAddress被映射到FooId.postAddress。 FooId然後「指向可寫 PostAddressId類,這與上面的@EmbeddedId邏輯沒有區別。至少邏輯和我沒有什麼不同。唯一的區別是,因爲我使用的是@EmbeddedId,所以可寫@Column註釋最終在@Embeddable類中,這是有效的。 (JPA只允許在@Embeddable類@Embedded,@Basic,@Column,@Temporal,@Enum和@Binary AFAIK中進行簡單的註釋。)
有什麼我失蹤了嗎? JPA 2.0規範在這裏說的是什麼?
或者這是EclipseLink中的錯誤嗎?
最後說明:這個問題顯然類似於JPA (Hibernate, EclipseLink) mapping: why doesn't this code work (chain of 2 relationships using JPA 2.0, @EmbeddedId composite PK-FK)?但不一樣。與此同時,鏈接問題的EL已經修復,我正在使用EL的固定版本,因此問題不盡相同。這個只是關於JPA 2.0 @EmbeddedId中@JoinColumn的只讀屬性,在EclipseLink中使用嵌套ID類+ @MapsId。
主題在EclipseLink論壇中繼續:http://www.eclipse.org/forums/index.php/m/671130/ – Kawu 2011-05-16 20:18:58