JPA @MapsId与@JoinColumn(updatable=false, insertable=false)的区别

10

在我看来,以下两种映射方式几乎没有区别。这是一个基于 @MapsId javadoc 的例子:

// parent entity has simple primary key

@Entity
public class Employee {
   @Id long empId;
   ...
}

// dependent entity uses EmbeddedId for composite key

@Embeddable
public class DependentId {
   String name;
   long empid;   // corresponds to primary key type of Employee
}

@Entity
public class Dependent {
   @EmbeddedId DependentId id;
    ...
   @MapsId("empid")  //  maps the empid attribute of embedded id
   @ManyToOne Employee emp;
}

如果我将Dependent的映射更改为什么会发生呢:

@Entity
public class Dependent {
   @EmbeddedId DependentId id;

   @ManyToOne
   @JoinColumn("empid", insertable=false, updatable=false)
   Employee emp;
}

上述两种方法的区别是什么?


你已经测试过了吗? - RMachnik
是的,我做了,但还有一些其他奇怪的问题。但根据文档的描述,我找不到它们之间的任何区别。你能给一些提示吗? - Adrian Shum
那么对你来说哪个更好呢?我过去常用JoinColumn,对我来说很有效。但现在我看到MapsId了,也想知道它会怎么工作 ;) - RMachnik
@Rafik991 我也是一样 :P 我以前使用JoinColumn,但我看到MapsId(可能是JPA2的新功能?或者我之前错过了)。问这个问题的原因只是为了了解区别 :P - Adrian Shum
2个回答

7
因此,当表中只有一个外键时,我测试了@MapsId,没有任何区别。但是对于那些有两个外键指向同一张表的表格,例如UserTableEmailTable,我就遇到了问题。使用@MapsId时Hibernate会抛出异常,所以我只能回到旧的@JoinColumn方式进行操作。这是我在使用这些注释时遇到的唯一区别。

1
是的,事实上我也遇到了那个异常,但我怀疑它只是其他问题,因为从文档中可以看出,MapsId应该适用于(并且是针对)这种情况。我更想知道这两者之间在设计特性方面的区别。不过,还是非常感谢你的更新,因为它也告诉我,我不是唯一遇到那个异常的人 ;) LOL - Adrian Shum

5

我使用@MapsId和@JoinColumn的组合来避免在关联实体时在数据库中创建多余字段。如果我不使用@JoinColumn,将会在数据库中创建一个额外的字段。

@Entity
public class BookingsModel implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private SlotDateModel slotDateModelObj;

    @JsonProperty
    String slotnumber;

    @MapsId("memberid")
    @JsonBackReference
    @ManyToOne
    @JoinColumn(name="memberid",referencedColumnName = "memberid")
    @NotNull
    MemberModel memberModel;
.
.
.
}

@Entity
public class MemberModel implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @JsonProperty
    @Id
    String memberid;

    @JsonProperty
    String name;

    @JsonIgnore
    String phoneno;

    @JsonManagedReference
    @OneToMany
    Set<BookingsModel> bookings;
    .
    .
    .
    }

@Embeddable
public class SlotDateModel implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    String memberid;

    String slotdate;
.
.
.
}

@JoinColumn生成的表格

@JoinColumn生成的表格

当@JoinColumn被注释时生成的表格 可以看到添加了额外的字段“member_model_memberid”。

当@JoinColumn被注释时生成的表格


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接