使用JPA CompositeKey使用另一个实体的属性

时间:2013-10-07 14:55:48

标签: jpa

我尝试搜索,但在找到我想要的东西时遇到了问题。我有以下架构(*表示主键)

USER
  *UserId
  -Desc
Registration
  *DeviceId
  *UserId
  -date

所以我想为注册创建一个主键,如...

@Embeddable
public class RegPk{
    private String deviceId;
    private User user;
    @Column(name="DEV_ID")
    public String getDevId(){
      return deviceId;
    }
    ...
    @ManyToOne
    @JoinColumn(name="USER_ID", referencedColumnName="USER_ID")
    public User getUser() {
      return user;
    }
    ...
}

这是对的吗?当我持续存在时,它会在注册时更新USER_ID字段吗?

当我尝试这种事情时,我得到以下内容......

  

[10/7/13 13:37:07:156 EDT] 000000ae webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E:[Servlet Error] - [Hello]:org.apache.openjpa。 util.MetaDataException:由类“class org.me.mfa.jpa.Registration”指定的id类与类的主键字段不匹配。确保您的标识类与持久类型具有相同的主键,包括pk字段类型。不匹配的属性:“用户”

那么现在呢?

2 个答案:

答案 0 :(得分:1)

JPA不允许主键类包含关系,只包含基本类型。 JPA 2.0允许关系成为ID的一部分,但您可以将关系移动到实体类,并使RegPk包含deviceId和UserId。然后,设备 - 用户关系将标记为@Id或@MapsId(“user”),具体取决于您是否要在实体中使用@PKClass或@EmbeddedId。有关使用pk类的示例,请参阅http://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/DerivedIdentifiers

在JPA 1.0中,您将使用类似的设置,但您的设备 - 用户关系将被标记为只读(通过指定@PrimaryKeyJoinColumn注释,或通过使用insertable = false标记@JoinColumn,updatable = false )。然后,您需要手动设置主键基本映射值,直接从引用的User实体中提取值。这当然要求已经分配用户中的id,如果两个对象都是新的,则可能需要额外的工作。

答案 1 :(得分:0)

我会将cascade = CascadeType.ALL添加到@ManyToOne注释,以转发User实体的持续操作。

看起来像:

    ...
    @ManyToOne(optional=true, cascade = CascadeType.ALL)
    @JoinColumn(name="USER_ID", referencedColumnName="USER_ID")
    public User getUser() {
      return user;
    }
    ...

好吧,如果没有其他错误,它可以工作。我对optional=true感到困惑,因为它可以提供deviceId,null的ID,但也可以。