1

是我做错了什么还是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,因此继承了它的键

@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或做错了什么。有人请帮帮我。

4

1 回答 1

0

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

  1. 我首先想到的是您用户的 PK 包含password. 密码通常是可更改的,主键则不是。此外,您是否会期望有两个不同的用户使用相同的电子邮件但不同的密码?可能不是。删除MemberID并更改Member_Details为有一个简单@Ide_mail代替:

    @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;
    }
    

    并且@MapsIdonUserComment将更改为@MapsId("e_mail").

  2. 上面的更改应该足以避免您的问题,但如果是我,我也会摆脱复合主键UserComment。简单来说,你可以给它 aUUID然后在e_mailand上加上一个唯一的约束timeOfComment

于 2013-08-26T18:38:55.710 回答