【问题标题】:Making primary key same as foreign key in Hibernate entity在 Hibernate 实体中使主键与外键相同
【发布时间】:2020-05-02 06:37:13
【问题描述】:

我是 Hibernate 的新手。我正在研究以下两个实体:

实体1如下:

@Entity
@Table(name = "vm_user")
public class VmUser implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "last_modified_by")
    private String lastModifiedBy;

    @Column(name = "created_date")
    private Instant createdDate;

    @Column(name = "last_modified_date")
    private Instant lastModifiedDate;

    @OneToOne
    @JoinColumn(unique = true)
    private User user;             <--- HOW WILL I DENOTE THIS PRIMARY KEY OF VMUSER ENTITY ?

在mysql的关联表中,即vm_useruser_id既是主键也是外键,指的是与User实体关联的user表的id。

实体2如下:

@Entity
@Table(name = "my_entity")
public class MyEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "last_modified_by")
    private String lastModifiedBy;

    @Column(name = "created_date")
    private Instant createdDate;

    @Column(name = "last_modified_date")
    private Instant lastModifiedDate;

    @ManyToOne
    private A a;

    @OneToOne
    @JoinColumn(unique = true)
    private B b;

在mysql的关联表my_entity中,主键是id of aid of b的组合。我不知道如何在 Hibernate 实体 MyEntity 中表示这一点。

关于同样的,我已经浏览了一些帖子:Hibernate foreign key as part of primary keyJPA & Hibernate - Composite primary key with foreign key,但不知道如何做到这两个?

【问题讨论】:

  • 还显示您的用户实体.. 用户主键是 int 还是 string?
  • @GolamMazidSajib,id 是与用户休眠实体关联的用户表整数类型的主键。

标签: java mysql hibernate jpa


【解决方案1】:

解决办法是@MapsId

例如

@Entity
@Table(name = "vm_user")
public class VmUser implements Serializable {

    @Id
    @Column(name = "user_id")    
    private Integer id;

    @MapsId
    @OneToOne
    private User user;  

您也可以删除@JoinColumn(unique = true),因为@Id 已经使其独一无二。

public class MyEntityPk implements Serializable {

   private Integer aId;
   private Integer bId;

   // IMPORTANT: Override equals() and hashCode()
}


@IdClass(MyEntityPk.class)
@Entity
@Table(name = "my_entity")
public class MyEntity implements Serializable {

    @Id
    private Integer aId;
    @Id
    private Integer bId;

    @MapsId("aId")
    @ManyToOne
    private A a;

    @MapsId("bId")
    @OneToOne
    private B b;

请在 Hibernate 文档https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#identifiers-derived中找到更多信息

【讨论】:

  • 您将 id 声明为主键,我认为 OP 想让 user_id 作为主键
  • 我添加了 ColumnMapping
  • @SimonMartinelli 您能否也为实体 2 提出一种方法?
  • 我也为第二个实体添加了解决方案。重要的是 PK 类必须实现 Serializable 并覆盖 equals 和 hashCode
  • @SimonMartinelli 是的。您的解决方案中有一个小疑问。您不必添加任何映射,例如属性映射到哪个 id 吗?我的意思是这里我们有两个 Ids 注释和两个 MapIds 注释。那么它如何确定 aId 对应于 A 或 B,与 bId 相同?如果我错了,请纠正我。
【解决方案2】:

你需要使用@EmbeddedId@MapsId

@Entity
@Table(name = "vm_user")
public class VmUser implements Serializable {
   @Id
    @Column(name = "user_id")    
    private Integer id;

    @MapsId("user_id")
    @OneToOne
    private User user;  
}

你可以对 MyEntity 做同样的事情,如下所示,

@Embeddable
class BKey {
  private int aId;
  private int bId;
}


@Entity
@Table(name = "my_entity")
public class MyEntity implements Serializable {

    @EmbeddedId
    private BKey primaryKey;

    @MapsId("aId")
    @ManyToOne
    private A a;

    @MapsId("bId")
    @OneToOne
    @JoinColumn(unique = true)
    private B b;
}

【讨论】:

  • @code-mode 我没有任何 vm_user 列。所以我猜你的答案中会省略 vm_user 列。请纠正我,如果我错了。另外,关于实体 2,您能否提出一种方法?
  • vm_uservm_user_id 添加ID。你可以为MyEntity做同样的事情
  • @code-mode,对于 vm_user 表 user_id 是主键。
  • 更新答案。我希望它有所帮助。
  • @code-mode,一个小疑问。在 MapsId 注释中,“aId”和“bId”指的是 BKey 类的属性,对吧?它可能不一定与基础表的实际列名相同。为此,我必须在 BKey 类中的这些属性上方添加注释 Column(name = "a_id") 和 Column(name = "b_id") 我猜。如果我错了,请纠正我。
【解决方案3】:

VM 用户类

public class VmUser implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

@OneToOne
@JoinColumn(name="ID")
private Users user;

用户类

public class Users implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

@OneToOne(mappedBy="user")
private VmUser vmUser;

一个类

@Entity
public class A implements Serializable {

@Id
private long id;

@OneToMany(mappedBy="a")
private List<MyEntity> myEntitys;

B级

@Entity
public class B implements Serializable {

@Id
private long id;

@OneToMany(mappedBy="b")
private List<MyEntity> myEntitys;

MyEntity 类

@Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;

@EmbeddedId
private MyEntityPK id;


@ManyToOne
@JoinColumn(name="ID1")
private A a;

@ManyToOne
@JoinColumn(name="ID2")
private B b;

MyEntityPK 类

@Embeddable
public class MyEntityPK implements Serializable {

@Column(insertable=false, updatable=false)
private long id1;

@Column(insertable=false, updatable=false)
private long id2;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 2011-07-20
    相关资源
    最近更新 更多