@MapsId

@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @OneToOne(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.LAZY)
    private Tuition tuition;

    /* Getters and setters */   
}
@Entity
@Table(name = "tuition")
public class Tuition {
    @Id
    private Long id;
    private Double fee;

    @MapsId
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "student_id")
    private Student student;

    /* Getters and setters */    
}

上面的代码和之前不同的地方在于,对于 Tuition 实体类,去掉了 @GeneratedValue 注解,加上了 @MapsId 注解。

@MapsId 的作用在于,将 student_id 的值映射到了 id 上。也就是说,JPA 自动建表时,tuition 表中就只有 id 没有 student_id 了,并且也没有指定 id 自动生成策略,因为 id 现在应该使用 student_id 的值。

@MapsId 副作用:使用 @MapsId 注解之后,任何嵌套或递归的 Projection 都将被设置为 null

除非你确定该实体只与某个实体有依赖关系,否则不要使用 @MapsId

我还是推荐不使用 @MapsId,免得给自己带来麻烦。

最后更新于