Reputation: 31
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.
Upvotes: 3
Views: 4684
Reputation: 31
I ended up doing what I wouldn't, I removed the nullable=false
constraint in OrderLine.orderId
and I added an assertion into my code to ensure that no one can set orderId
to null.
Upvotes: 0
Reputation: 8219
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();
Upvotes: 4
Reputation: 894
In Order, it should be @onetomany and mappedBy orderline_id. In Orderline, you should @manytoone and add @joincolumn with name ID..
Upvotes: 0