Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change name of foreign key constraint in One-to-Many unidirectional relation in Hibernate

I'm using Hibernate version 5.2.10.

Here is my relation in Order entity:

@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;

}

And in OrderLine I have:

@Entity
public class OrderLine {

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

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

}

All is working just fine, but now I want to change the name of the database FK constraint, so:

Order (now I use @JoinColumn instead of "mappedBy"):

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

OrderLine:

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

In this situation I have a problem when deleting an Order, because Hibernate sets the orderId to null before deleting the Order and the OrderLines, violating the not null orderId constraint.

To avoid this, I have to remove the nullable = false (but I do not want!).

Is there a solution? Can I change the name of the database FK constraint while using the "mappedBy"?

EDIT

As primary key identifier, I use a UUID version 4 (random) base64 encoded. After removing the padding chars, it is exactly 22 chars long. The ID is generated and assigned at construction time of any entity. But this is not related to my problem.

like image 906
Farr Avatar asked Dec 17 '25 06:12

Farr


1 Answers

The following approach seems to work:

@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;
    ...
}

I have used Hibernate auto-generated UUIDs but idea is same as yours. The database schema is:

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

Removing orders works too.


UPDATE: a few operations on the entities

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();
like image 58
wypieprz Avatar answered Dec 19 '25 19:12

wypieprz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!