Вам нужна таблица ассоциаций, которая часто строится в JPA по разным причинам, главным образом для контроля над тем, что происходит в таблице, или в этом случае для отображения n-way M: N отношений.
Создайте все своиОбъекты:
@Entity
public class User {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String userName;
@OneToMany(mappedBy="user")
private Set<UserDepartmentRoleAssociation> associations;
... etc
}
и
@Entity
public class Department {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String department;
@OneToMany(mappedBy="department")
private Set<UserDepartmentRoleAssociation> associations;
... etc
}
и
@Entity
public class Role {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String role;
... etc
}
и создайте свою таблицу ассоциации и класс идентификатора.
@Entity
public class UserDepartmentRoleAssociation {
@EmbeddedId private UserDepartmentRoleAssociationId id;
@ManyToOne @MapsId("userId")
private User user;
@ManyToOne @MapsId("departmentId")
private Department department;
@ManyToOne @MapsId("roleId")
private Role role;
public UserDepartmentRoleAssociation() {
id = new UserDepartmentRoleAssociationId();
}
... etc
}
и
@Embeddable
public class UserDepartmentRoleAssociationId implements Serializable {
private Integer userId;
private Integer departmentId;
private Integer roleId;
... etc
}
и чтобы сохранить связь, затем ...
User user = new User();
user.setUserName("user1");
Department department = new Department();
department.setDepartment("department 1");
Role role = new Role();
role.setRole("Manager");
UserDepartmentRoleAssociation association = new UserDepartmentRoleAssociation();
association.setUser(user);
association.setDepartment(department);
association.setRole(role);
em.persist(user);
em.persist(department);
em.persist(role);
em.persist(association);
и прочитать ее с помощью функции fetch затем
User user = em.createQuery("select u from User u left join fetch u.associations ass left join fetch ass.department left join fetch ass.role where u.id = :id", User.class).setParameter("id", 1).getSingleResult();
Обратите внимание, что я использовалSet
вместо List
в Department
и User
, что вызывает гораздо меньше проблем в этих случаях.Кроме того, мне не нужно создавать associations
, когда я сохраняю отношения, потому что UserDepartmentRoleAssociation
является владельцем объекта и, следовательно, сохраняет его.Наборы associations
создаются JPA при чтении записи.