Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate EclipseLink:多列、一对一、JPA 2.0@EmbeddedId使用@MapsId失败,@JoinColumn上为只读(比较派生标识)_Hibernate_Jpa_Mapping_Jpa 2.0_Eclipselink - Fatal编程技术网

Hibernate EclipseLink:多列、一对一、JPA 2.0@EmbeddedId使用@MapsId失败,@JoinColumn上为只读(比较派生标识)

Hibernate EclipseLink:多列、一对一、JPA 2.0@EmbeddedId使用@MapsId失败,@JoinColumn上为只读(比较派生标识),hibernate,jpa,mapping,jpa-2.0,eclipselink,Hibernate,Jpa,Mapping,Jpa 2.0,Eclipselink,我的设计如下: (来源:) 简单逻辑:Foos使用多列PK来使用相同的列(相同的键)发布地址 以下是JPA 2.0@EmbeddedId的映射(使用FooId中的嵌套ID类PostAddressId和Foo中的@MapsId注释映射到它): 堆栈跟踪: Exception [EclipseLink-46] (Eclipse Persistence Services - 2.3.0.v20110429-r9282): org.eclipse.persistence.exceptions.Desc

我的设计如下:


(来源:)

简单逻辑:Foos使用多列PK来使用相同的列(相同的键)发布地址

以下是JPA 2.0@EmbeddedId的映射(使用FooId中的嵌套ID类PostAddressId和Foo中的@MapsId注释映射到它):

堆栈跟踪:

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、updateable=false定义的,以指示嵌入的ID属性是可写的

注意,我并不是在寻找一个有效的解决方案,我只需删除只读insertable=false、updateable=false的内容就可以了。然而,问题是为什么上述映射在日食中失败。Hibernate对代码没有问题。此外,使用JPA 2.0@IdClass派生标识的以下功能等效代码(在EL中运行时不会出现问题)如下所示:

@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、updateable=false属性。Foo.postAddress通过将它们命名为相同的名称来映射到FooId.postAddress。FooId然后“指向”可写的PostAddressId类,它与上面的@EmbeddedId逻辑没有什么不同。至少逻辑对我来说没有什么不同。唯一的区别是,因为我使用@EmbeddedId,可写@Column注释最终位于@Embedded类中,这是有效的。(JPA只允许在@Embedded classes@Embedded、@Basic、@Column、@Temporal、@Enum和@Binary AFAIK中使用简单注释。)

我有什么遗漏吗?JPA2.0规范在这里说了什么

或者这是EclipseLink中的一个bug?


最后一点注意:这个问题显然类似于但不相同。同时,链接问题的EL已经修复,我使用的是固定版本的EL,所以问题不一样。这一个仅涉及JPA 2.0@EmbeddedId中@JoinColumn上的只读属性,使用EclipseLink中的嵌套ID类+@MapsId。

EclipseLink将MapsId解释为表示该关系控制Foos表中定义的contact_ID和ordinal_nbr列。因此,当您将关系字段标记为只读时,这意味着这些字段没有可写映射-mapsId告诉提供程序需要从关系中使用值,但关系是只读的


你为什么要使用mapsId而不是仅仅将你的关系标记为ID然后使用pk类呢

在EclipseLink论坛上继续讨论以下主题:
@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;

    ...
}