1:n disable constraints for the n-side?

Tags: , , ,



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 !

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.



Source: stackoverflow