且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

2个外键从不同实体进入新表休眠

更新时间:2022-03-04 08:57:27

您需要一个关联表,该表通常出于各种原因而在JPA中构建,主要是为了控制表中的内容或在这种情况下映射n路M:N关系.

You need an association table, often constructed in JPA for various reasons mostly to do with control over what goes in the table or in this case mapping an n-way M:N relationship.

创建所有实体:

@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
}

并创建关联表和ID类.

and create your association table and id class.

@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);

,然后通过join fetch进行阅读

and to read it with join fetch then

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();

请注意,我在DepartmentUser中使用了Set而不是List,这在这些情况下引起的问题要少得多.另外,当我保持关系时,我不必创建associations,因为UserDepartmentRoleAssociation是拥有实体,因此也可以进行持久化. associations集是由JPA在读取记录时创建的.

Note that I have used a Set instead of a List in Department and User which causes much less problems in these cases. Also, I don't have to create associations when I persist the relationship because the UserDepartmentRoleAssociation is the owning entity and therefore does the persisting. The associations sets are created by JPA when it reads a record.