Java 无法将继承的复合键用作JPA2中的派生id

Java 无法将继承的复合键用作JPA2中的派生id,java,jakarta-ee,jpa,eclipselink,Java,Jakarta Ee,Jpa,Eclipselink,我是否做错了什么,或者这在JPA2/eclipselink中不受支持,让我用代码解释一下 @Embeddable public class MemberID implements Serializable { private String e_mail; private String password; //...no-arg constructor, getter and setter 下面的实体使用MemberID作为复合键 @Entity @Table(

我是否做错了什么,或者这在JPA2/eclipselink中不受支持,让我用代码解释一下

 @Embeddable
public class MemberID implements Serializable {
    private String e_mail;
    private String password;
        //...no-arg constructor, getter and setter
下面的实体使用MemberID作为复合键

@Entity
@Table(name="MEMBER_DETAILS")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="GROUPNAME", discriminatorType=DiscriminatorType.STRING,   length=20)
public class Member_Details implements Serializable {

@EmbeddedId
private MemberID memberIdentity;
...other code
下面的实体扩展了成员的详细信息,因此继承了其密钥

@Entity
@Table(name="INDIVIDUAL_USER")
@DiscriminatorValue("INDIVIDUAL_USER")
public class Individual_User extends Member_Details implements Serializable {    
    @OneToMany(mappedBy="userinfo", fetch=FetchType.EAGER)
private List<UserComment> userComments = new ArrayList<UserComment>();
... other code
下面的实体使用CommentID作为其复合键。我希望它依赖于实体单个用户,因此使用派生id。这就是为什么MemberID是其复合键的一部分

@Entity
@Table(name="USER_COMMENTS")
public class UserComment implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private CommentID commentIdentity;

@MapsId("memberId")
@ManyToOne
@JoinColumns({
@JoinColumn(name="E_MAIL", referencedColumnName="E_MAIL"),
@JoinColumn(name="PASSWORD", referencedColumnName="PASSWORD")
})
private Individual_User userinfo;
...other code
当我尝试部署时出现问题,会引发以下异常:

Caused by: Exception [EclipseLink-7321] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The field [MEMBER_DETAILS.PASSWORD] from the derived id mapping  [userinfo] from class [kariro.semaplace.talk.entities.UserComment] is an invalid id field from the reference class [kariro.semaplace.registration.entity.Individual_User]. Ensure there is a corresponding id mapping to that field. 
但是,当我将@ManyToOne关系从UserComment改为reffer,改为键入Member\u Details,而不是其子类型Individual\u User时,它不会出现任何问题,但我担心这会在以后带来更多问题,或者影响应用程序的功能。
我真的不知道eclipselink是不允许继承ID用作派生ID,还是我做错了什么。有人请帮助我。

我不知道为什么会出现错误,但您可以通过简化实体来完全避免这个问题

  • 我首先想到的是,你的用户的PK包括
    密码
    。密码通常是可更改的,而主键则不是。此外,您是否希望有两个不同的用户使用相同的电子邮件但密码不同?可能不会。删除
    MemberID
    并更改
    memberu\u详细信息
    以获得一个简单的
    @Id
    ,只包含
    电子邮件

    @Entity
    @Table(name="MEMBER_DETAILS")
    @Inheritance(strategy=InheritanceType.JOINED)
    @DiscriminatorColumn(name="GROUPNAME", discriminatorType=DiscriminatorType.STRING, length=20)
    public class Member_Details implements Serializable
    {
      @Id
      private String e_mail;
      private String password;
      // ...
    }
    
    CommentID
    也会改变:

    @Embeddable
    public class CommentID implements Serializable
    {
      private String e_mail;
    
      @Temporal(TemporalType.TIMESTAMP)
      @Column(name="TIME_POSTED")
      private Date timeOfComment;
    }
    
    UserComment
    上的
    @MapsId
    将更改为
    @MapsId(“电子邮件”)

  • 上面的更改应该足以避免您的问题,但如果是我,我也会去掉
    UserComment
    上的复合主键。简单地说,您可以给它一个
    UUID
    ,然后对
    e\u-mail
    timeOfComment
    设置一个唯一的约束


  • 你好,丹尼,谢谢你的回复。我肯定会调查你提出的更改,但我真的很想知道上述行为的根本原因…@Don_Kariro当你用
    成员详细信息
    替换
    个人用户
    时效果很好,这让我认为这是一个EclipseLink bug。它不能正确处理EmbeddedId位于超类中的情况。如果我是你,我会提交一份bug报告,看看他们会怎么说。规范中没有任何内容表明您所做的是错误的(除非我遗漏了什么)。也许还值得一试,看看你是否可以用
    @IdClass
    而不是
    @embeddeble
    @Don_Kariro来完成这项工作。我很好奇。你有没有想过?你好,丹尼,很抱歉我花了很长时间才回到这个话题。我完全按照你上面的建议做了。我只是简单地重构了我的实体,它工作了,但仍然无法理解问题的根本原因。。。这一定是一个日食虫。
    @Embeddable
    public class CommentID implements Serializable
    {
      private String e_mail;
    
      @Temporal(TemporalType.TIMESTAMP)
      @Column(name="TIME_POSTED")
      private Date timeOfComment;
    }