问题
I'm struggling to model the relationship between multiple tables (parents) that share a single table (child).
Given the following parent 1 table (the other parent tables 2,3 and so on are similar):
@Entity
@Table (name="parent1")
public class ParentEntity1 {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
// relationship with child table
@OneToMany(mappedBy = "parentId", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ChildEntity> children;
// other columns of parent 1
}
and the following child table:
@Entity
@Table (name="children")
public class ChildEntity {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
// points to the parent type; 1, 2, and so on
@Column(name="parent_type")
private Integer parentType;
@Column(name="parent_id")
private Integer parentId;
// some other data that belongs to ChildEntity
}
How do I persist one parent object and multiple children while creating the relationship? Note that the parent type is a column in the child table, and that both parent and child ids are auto-generated.
回答1:
What you should do is to actually attach the ParentEntity to the ChildEntity. In JPA this relation from m:1 is realized by @JoinColumn. You don't need to store parent type in a child entity - it would be a sign of a bad design. Type of a parent should be as close to its entity as possible. So simply put it in that entity:
@Entity
@Table (name="children")
public class ChildEntity {
@Id Integer parentId;
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@ManyToOne
@JoinColumn(name="parent")
private ParentEntity parent;
// some other data that belongs to ChildEntity
//all setters and getters / lombok
}
@MappedSuperclass
public abstract class ParentEntity {
@OneToMany(mappedBy = "parentId", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ChildEntity> children;
@Column(name="parent_type")
private Integer parentType;
//all setters and getters / lombok
}
@Entity
@Table (name="parent1")
public class ParentEntity1 extends ParentEntity {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
// other columns specific to parent 1
//all setters and getters / lombok
}
@Entity
@Table (name="parent2")
public class ParentEntity2 extends ParentEntity {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
// other columns specific to parent 2
//all setters and getters / lombok
}
and to persist a parent with several children you do something like that:
ParentEntity pOne = new ParentEntity1();
ParentEntity pTwo = new ParentEntity2();
ChildEntity c1 = new ChildEntity();
ChildEntity c2 = new ChildEntity();
ChildEntity c3 = new ChildEntity();
Set<ChildEntity> childrenOne = new HashSet<>();
childrenOne.add(c1);
childrenOne.add(c2);
Set<ChildEntity> childrenTwo = new HashSet<>();
childrenTwo.add(c3);
pOne.setChildren(childrenOne);
pOne.setType(1);
// ...
em.getTransaction().begin();
em.persist(pOne);
em.getTransaction().commit();
// ...
pTwo.setChildren(childrenTwo);
pTwo.setType(2);
// ...
em.getTransaction().begin();
em.persist(pTwo);
em.getTransaction().commit();
// ...
and that's all. Note that you never instantiate ParentEntity class (as it's abstract). You can have multiple parent tables where each of them refers to single child table by the id. Moreover, you store information about the type of each subsequent parent entity in its class by inheritance from ParentEntity. I hope it solves your problem.
来源:https://stackoverflow.com/questions/28030916/modeling-single-child-multiple-parent-tables