0

I am trying to implement a single table Hibernate inheritance strategy with a DB table "persons".

I have a family which contains a husband, a wife, a list of children and a list of other inmates. Each person may be a member of many families (i.e. a husband may be a husband in one family and a child in other).

@Entity
@Table(name = "families")
public class Family extends BaseObject {
    private Parent husband;
    private Parent wife;
    private String surname;

    private List<Child> children = new ArrayList<Child>();
    private List<Other> others = new ArrayList<Other>();

    @ManyToOne(optional = true, cascade = CascadeType.ALL)
    @JoinColumn(name = "husband_id", nullable = true)
    public Parent getHusband() {
        return husband;
    }

    @ManyToOne(optional = true, cascade = CascadeType.ALL)
    @JoinColumn(name = "wife_id", nullable = true)
    public Parent getWife() {
        return wife;
    }

    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="persons_families", joinColumns=@JoinColumn(name="family_id"), inverseJoinColumns=@JoinColumn(name="person_id"))
    public List<Other> getOthers() {
        return others;
    }

    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="persons_families", joinColumns=@JoinColumn(name="family_id"), inverseJoinColumns=@JoinColumn(name="person_id"))
    public List<Child> getChildren() {
        return children;
    }

Persons is a common class for all persons:

@Entity
@Table(name = "persons")
@DiscriminatorColumn(name = "type")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

public class Person extends BaseObject {
    private List<Family> families;

    @ManyToMany(cascade=CascadeType.ALL)  
    @ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name="persons_families", joinColumns=@JoinColumn(name="person_id"), inverseJoinColumns=@JoinColumn(name="family_id"))
    public List<Family> getFamilies() {
        return families;
    }

Child and Other and Parent classes are identical:

@Entity
@Table(name = "persons")
@DiscriminatorValue(value = "children")
public class Child extends Person {}

@Entity
@Table(name = "persons")
@DiscriminatorValue(value = "others")
public class Other extends Person {}

@Entity
@Table(name = "persons")
@DiscriminatorValue(value = "parents")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Parent extends Person {}

Now during the system startup I have the following problem:

org.hibernate.MappingException: Repeated column in mapping for entity: org.parafia.model.Other column: type (should be mapped with insert="false" update="false")

What could I do about that? Does my model make sense?

Best regards

Gandalf
  • 155
  • 1
  • 12

1 Answers1

1

Does my model make sense?

It does not: if your goal is that, say, Alice is a mother in some family and also a child in some other, what should the type of Alice's row in persons be? Should Alice be an instance of Parent or Child?

Subclasses must be disjunct sets.

giorgiga
  • 1,758
  • 12
  • 29
  • My fault, I understand. It seems that if I would like to have Alice as mother and a child at the same time I need a hibernate JOINED inheritance strategy. And have a table persons with some basic info about Alice and the same record in children and parents tables. Is that right? – Gandalf Feb 22 '18 at 15:04
  • No @Gandalf: an instance of `Child` *cannot* also be an instance of `Parent`: that's in Java too, not only in Hibernate :-) – giorgiga Feb 22 '18 at 19:21
  • OK :-) So it seems that I need to use one common table persons. Family is linked to some person with mother_id and to another person with father_id. Family also have a list of children and a list of other inmates. Is there a way to have a joining table for many-to-many association with additional field of the type of this association (child or other inmate)? – Gandalf Feb 24 '18 at 15:27
  • @Gandalf It's been a while since I last used JPA, but IIRC `@ManyToMany` only worked for "simple" (unqualified) relations. Regardless, I'd recommend making an entity out of the many-to-many table (with id and all): the id makes everything simpler and – sooner or later – you are bound to need to add more cols to the table (it *always* happens) – giorgiga Mar 01 '18 at 22:18
  • Do NOT use composite keys. For any reason. Ever. :) – giorgiga Mar 01 '18 at 22:19