Hibernate/JPA中如何正确使用@OneToMany双向关系?


在实施@OneToMany双向关系时,有很多方法会搞砸。这里说明一下最佳实践方式:
关键点:

  • 始终从父级到子级实现级联
  • 在父类上使用mappedBy
  • 在父类上使用orphanRemoval以删除父类不再引用的子类
  • 在父类上使用helper方法可以使关联的两端保持同步
  • 始终使用延迟提取
  • 使用自然/业务key或使用实体标识符并覆盖equals(),hashCode()如此处所示

源代码可以在这里找到  。

父类:
@Entity
public class Tournament implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, 
            mappedBy = "tournament", orphanRemoval = true)
    private List<TennisPlayer> tennisPlayers = new ArrayList<>();


子类:
@Entity
public class TennisPlayer implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "tournament_id")
    private Tournament tournament;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Tournament getTournament() {
        return tournament;
    }

    public void setTournament(Tournament tournament) {
        this.tournament = tournament;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof TennisPlayer)) {
            return false;
        }
        return id != null && id.equals(((TennisPlayer) obj).id);        
    }

    @Override
    public int hashCode() {
        return 2018;
    }
}