The Problem
I have a 1:n relation, but the n side shouldnt rely on constraints. So i actually wanna insert a EntityPojo via its future id, when its not saved yet ( Lets ignore that its a bad practice ). This looks kinda like this.
var relation = new RelationshipPojo(); . . . relation.targets.add(session.getReference(futureID, EntityPojo.class)); session.save(relation); // A few frames later session.save(theEntityPojoWithTheSpecificId);
Cascading is not possible here, i only have its future ID, not a reference to the object i wanna save. Only its id it will have in the future.
@Entity @Table(name = "relationship") @Access(AccessType.FIELD) public class RelationshipPojo { . . . @ManyToMany(cascade = {}, fetch = FetchType.EAGER) public Set<EntityPojo> targets = new LinkedHashSet<>(); }
Question
How do we tell hibernate that it should ignore the constraints for this 1:n “target” relation ? It should just insert the given ID into the database, ignoring if that EntityPojo really exists yet.
Glad for any help on this topic, thanks !
Advertisement
Answer
For a much simpler solution, see the EDIT below
If the goal is to insert rows into the join table, without affecting the ENTITY_POJO
table, you could model the many-to-many association as an entity itself:
@Entity @Table(name = "relationship") @Access(AccessType.FIELD) public class RelationshipPojo { @OneToMany(cascade = PERSIST, fetch = EAGER, mappedBy = "relationship") public Set<RelationShipEntityPojo> targets = new LinkedHashSet<>(); } @Entity public class RelationShipEntityPojo { @Column(name = "entity_id") private Long entityId; @ManyToOne private RelationshipPojo relationship; @ManyToOne @NotFound(action = IGNORE) @JoinColumn(insertable = false, updatable = false) private EntityPojo entity; }
This way, you’ll be able to set a value to the entityId
property to a non-existent id, and if an EntityPojo
by that id is later inserted, Hibernate will know how to populate relationship
properly. The caveat is a more complicated domain model, and the fact that you will need to control the association between RelationshipEntityPojo
and EntityPojo
using the entityId
property, not entity
.
EDIT Actually, disregard the above answer, it’s overly complicated. Turing85 is right in that you should simply remove the constraint. You can prevent Hibernate from generating it in the first place using:
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER) @JoinTable(inverseJoinColumns = @JoinColumn(name = "target_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))) public Set<EntityPojo> targets = new LinkedHashSet<>();
The only caveat is that when you try to load RelationshipPojo.targets
before inserting the missing EntityPojo
, Hibernate will complain about the missing entity, as apparently @NotFound
is ignored for @ManyToMany
.