在Hibernate中更改一对多单向关系中的外键约束名称

时间:2017-11-17 09:20:52

标签: java hibernate jpa foreign-keys constraints

我正在使用Hibernate版本5.2.10。

以下是我在订单实体中的关系:

@Entity
public class Order {

  @Id
  @Column(name = "ID", length = 22)
  private String id;

  @OneToMany(mappedBy = "orderId", cascade = CascadeType.ALL, orphanRemoval = true)
  private List<OrderLine> lines;

}

OrderLine 中,我有:

@Entity
public class OrderLine {

  @Id
  @Column(name = "ID", length = 22)
  private String id;

  @Column(name = "ORDER_ID", nullable = false, length = 22)
  private String orderId;

}

一切正常,但现在我想更改数据库FK约束的名称,所以:

订单(现在我使用@JoinColumn代替"mappedBy"):

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "ORDER_ID", foreignKey = @ForeignKey(name = "FKNAME"))
private List<OrderLine> lines;

订单行

@Column(name = "ORDER_ID", nullable = false, length = 22)
private String orderId;

在这种情况下,我在删除订单时遇到问题,因为Hibernate会在删除orderId之前将Order设置为 null OrderLines,违反了非null orderId约束。

为了避免这种情况,我必须删除 nullable = false (但我不想要!)。

有解决方案吗?我可以在使用"mappedBy"

时更改数据库FK约束的名称

修改

作为主键标识符,我使用UUID版本4(随机)base64编码。删除填充字符后,它恰好是22个字符长。在任何实体的构建时生成并分配ID。但这与我的问题无关。

3 个答案:

答案 0 :(得分:1)

以下方法似乎有效:

@Entity
public class Orders {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
    @Column(name = "ORDER_ID", length = 36)
    private String idc;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "ORDER_ID", foreignKey = @ForeignKey(name = "FK_NAME"))
    private List<OrderLine> lines;

    ...
}

@Entity
public class OrderLine {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
    @Column(name = "ORDERLINE_ID", nullable = false, length = 36)
    private String orderlineId;
    ...
}

我使用过Hibernate自动生成的UUID,但想法和你的一样。数据库架构是:

ORDERS                      ORDERLINE
------------                ----------------
ORDER_ID  PK --+            ORDERLINE_ID  PK
               +--FK_NAME-- ORDER_ID      FK

删除订单也有效。

更新:对实体的一些操作

OrderLine ol1 = new OrderLine();
OrderLine ol2 = new OrderLine();
OrderLine o13 = new OrderLine();
OrderLine ol4 = new OrderLine();
OrderLine ol5 = new OrderLine();
OrderLine ol6 = new OrderLine();
Orders o1 = new Orders(Arrays.asList(ol1));
Orders o2 = new Orders(Arrays.asList(ol2, o13));
Orders o3 = new Orders(Arrays.asList(ol4, ol5, ol6));

em.begin();
em.persist(o1);
em.persist(o2);
em.persist(o3);
em.commit();

em.begin();
Orders o = p.provider().find(Orders.class, id);
em.remove(o);
em.commit();

答案 1 :(得分:0)

按顺序,它应该是@onetomany和mappedBy orderline_id。在Orderline中,您应该@manytoone并添加名称为ID的

答案 2 :(得分:0)

我最终做了我不想做的事情,我删除了nullable=false中的OrderLine.orderId约束,并在代码中添加了一个断言,以确保没有人可以将orderId设置为null