三元关系hibernate保存在额外的表中

时间:2018-01-25 08:09:31

标签: java hibernate jpa

我有3个可以相互建立关系的实体。因此,解决此问题的一个好方法是使用另一个表来存储3个实体的3个ID。让我们说实体是X,Y和Z。

@Entity
public class XYZ {

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

    @ManyToOne
    @JoinColumn(name = "X_ID")
    private X x;

    @ManyToOne
    @JoinColumn(name = "Y_ID")
    private Y y ;

    @ManyToOne
    @JoinColumn(name = "Z_ID")
    private Z z;

    public XYZ(){

    }

}

实体X,Y和Z具有:

  • 他们自己的属性和主键
  • @OneToMany到属性私有XYZ上的X,Y和Z实体 XYZ;使它双向

实体XYZ对于实体X,Y和Z具有正常的getter和setter。我给出了整个实体。

实体X,Y和Z是父母,XYZ是孩子。因此,删除X,Y或Z应删除XYZ。

从两个实体之间的关系我知道你必须将孩子保存在父方面。例:  parent.addChild(C); parent.save();

如何在级联工作的情况下在新的XYZ中保存X,Y,Z? 我不想保存3次(在X,Y和Z上)。 很抱歉,如果这是一个显而易见的问题,但我还没有找到很好的例子,而且我的知识还不够。

我有这个,但不知道它是否正确:

XYZ test = new XYZ();
test.setX(new X());
test.setY(new Y());
test.setZ(new Z());
test.save();

现在,如果我删除X实体,是否自动删除了包含X实体的XYZ实体?

1 个答案:

答案 0 :(得分:0)

  

我有这个,但不知道它是否正确

我不确定test.save()是做什么的,但如果它调用EntityManager.persist(test),那么这就是正确的做法。

  

现在,如果我删除X实体,是否自动删除了包含X实体的XYZ实体?

默认不是。对于cascade = REMOVE映射,您需要@OneToMany,否则删除X将失败。请注意,与在批量删除查询中删除相关XYZ相比,这会带来性能开销。但是,如果单个X/Y/Z实体的关联数量很少,那么您应该没问题。

顺便说一下,如果XYZ的唯一目的是代表三元协会,我会考虑:

  • optional=false添加到@ManyToOne
  • 将多对一关联转换为复合主键(这种方式会自动防止重复)并删除人工ID
  • 如果您仍然想要一个人工ID,您至少应该定义一个涉及所有连接列的@UniqueConstraint(将连接列声明为updatable=false, nullable=false也可能是一个好主意,只是为了安全起见)