In a JPA setup, I have a graph-like structure of entities, featuring classes like:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vertex {
@Id
private String id;
@ManyToOne
private Scope parent;
@Column(name = "visibility_policy")
private String visibilityPolicy;
// ...
}
and
@Entity
public class Scope extends Vertex {
@OneToMany(mappedBy = "parent")
private final Set<Vertex> children= new HashSet<>();
@ElementCollection
@CollectionTable(name = "vertex", joinColumns = @JoinColumn(name = "parent_id", referencedColumnName = "id"))
@MapKeyColumn(name = "id")
@Column(name = "visibility_policy")
private final Map<String, String> childrenVisibility = new HashMap<>(); // how to get this to work?
// ...
}
What I would like to do is to join this vertex table on itself (id on parent_id) to find all the children of an entity, then get a map that maps any child's id to its visibilityPolicy.
The code above throws the following exception, followed by the usual Spring-Bean-Initialization Stack trace:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FKcjf5jdhsaxodbfg76lath3s5c:alias [id])) must have same number of columns as the referenced primary key (vertex [parent_id,vertex_id])
How can I implement this correcctly?
I feel like I'm way out of my league here, please help :)
CodePudding user response:
Just in case someone struggles with a similar problem, here's how I worked around it:
I made a separate entity that reads from the same table as the children I would have wanted to get the data from. (possible with @Table(name = "my_entity")
) Within that pseudo-entity-class I only specified the field I was interested in, so there is no unnecessary data loaded. This now also allows the parent to have an eagerly-fetched collection of its children (well, not the full children but only what's absolutely necessary of them) without severe performance drawbacks.