Search code examples
spring-boothibernatejpaspring-data-jpahibernate-mapping

Is possible to use JoinColumn to map OneToMany relation without ForeignKey and Association Entity?


I'm wondering how to map such a relationship:

@Table("master_a")
class MasterA{
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Where(clause = "type = 'MASTER_A'")
Set<Child> childs;
}

@Table("master_b")
class MasterB{
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Where(clause = "type = 'MASTER_B'")
Set<Child> childs;
}

@Table("child")
class Child{
Long id;
String type;
Long masterId;
}

Table Child:

| Id | Type | Master_Id |

| --- | --- | --- |

| 1 | MASTER_B | 1 |

| 2 | MASTER_A | 1 |

| 3 | MASTER_B | 1 |

Child table has only PK and indexed type/master_id fields (without foreign keys).

For constant values I used hibernate @Where condition, but how to map master_id variable? I tried in OneToMany:

@JoinColumn(foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT),name = "id", referencedColumnName = "master_id")

But Hibernate ignoring ForeignKey annotation and still search for database FK. I found "DiscriminatorColumn" annotation which can be used like in this question: When to use @DiscriminatorValue

But in my case Child entity is not a superclass - can this mechanism be used in other direction?

Child entity holds optional additional data for X enitities (I want store this data in one db table) and make Hibernate do subqueries for different masters types like: select c.* from child c where c.type='CONSTANT_MASTER_TYPE_BASE_ON_CLASS_TYPE' and c.master_id=?.id


Solution

  • Why are you defining a foreign key in your join column if you don't want one? Leave it off.

    All you will likely need is indexing on the child.masterId as it will be used on the Master fetches, and if you are controlling the column from the Child side, make the join column insertable=false, updatable=false

    @JoinColumn(name = "id", referencedColumnName = "master_id", insertable=false, updatable=false)