java - 无法在 JPA2 中使用继承的复合键作为派生 id

标签 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(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

下面的实体扩展了 Member_Details,因此继承了它的 key

@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

以下是包含 MemberID 作为其一部分的复合键。

@Embeddable
public class CommentID implements Serializable { 
private MemberID memberId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="TIME_POSTED")
private Date timeOfComment;
...other code

下面的实体使用 CommentID 作为其组合键。我希望它依赖于实体 individual_user,因此使用派生 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 更改为引用类型 Member_Details 而不是其子类型 individual_User 时,它可以正常工作,但我担心这会在以后带来更多问题,或者损害应用程序的功能。 我真的不知道 eclipselink 是否不允许继承的 id 用作派生 id 或者我做错了什么。请有人帮助我。

最佳答案

我不确定您为什么会收到错误,但您可以通过简化实体来完全避免该问题。

  1. 我首先想到的是您的用户的 PK 包含密码。密码通常是可以更改的,但主键则不能。另外,您是否希望有两个不同的用户拥有相同的电子邮件地址但密码不同?可能不会。删除 MemberID 并将 Member_Details 更改为仅 e_mail 的简单 @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("e_mail")

  2. 上述更改应该足以避免您的问题,但如果是我,我也会删除 UserComment 上的复合主键。简单来说,您可以给它一个 UUID,然后对 e_mailtimeOfComment 施加唯一约束。

关于java - 无法在 JPA2 中使用继承的复合键作为派生 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18417990/

相关文章:

java - 如何删除错误 UnsupportedOperationException 和可能的内存泄漏

java - 在 JBos 的 servlet 中使用 TCP 套接字

java - 并非所有 java 线程都启动

jpa - Eclipselink : How do you get the EntityManager in each bundle?

java - 如果我只有 .java 文件,用它们制作项目的最佳方法是什么?

java - 内部类 JPanel 的奇怪之处

Java 数组列表验证

java - 如何确保保存和解析对象字符串表示的格式正确关联

jpa - 有没有办法抑制 FindBugs 在静态编织生成的代码上生成警告?

JPA只执行union中的第一个select语句?