Hibernate中的多对多关系不会返回结果

时间:2017-02-07 11:58:00

标签: java hibernate many-to-many

我有两个bean类 - User和UserGroup:

用户:

@Entity
@Table(name = "user")
public class User implements Serializable {
    private static final long serialVersionUID = -7482853955996650586L;

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Integer id;

    @Column(name = "login")
    private String login;

    @ManyToMany
    @JoinTable(name = "user_x_userGroup",
        joinColumns = {
                @JoinColumn(
                        name = "user_id",
                        foreignKey = @ForeignKey(name = "FK_user_x_userGroup_user_id")
                ) },
        inverseJoinColumns = {
                @JoinColumn(
                        name = "userGroup_id",
                        foreignKey = @ForeignKey(name = "FK_user_x_userGroup_userGroup_id")
                ) })
    private List<UserGroup> userGroups;

    public User() {
        this.userGroups = new ArrayList<>();
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLogin() {
        return this.login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public List<UserGroup> getUserGroups() {
        return this.userGroups;
    }

    public void setUserGroups(List<UserGroup> userGroups) {
        this.userGroups = userGroups;
    }
}

用户组:

@Entity
@Table(name = "userGroup")
public class UserGroup implements Serializable, Comparable<UserGroup> {
    private static final long serialVersionUID = -5924845694417474352L;

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Integer id;

    @Column(name = "title")
    private String title;

    @ManyToMany(mappedBy = "userGroups")
    private List<User> users;

    public UserGroup() {
        this.users = new ArrayList<>();
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<User> getUsers() {
        return this.users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
}

我正在测试UserServiceTest中用户组列表的大小是否为

public class UserServiceTest {

    @BeforeClass
    public static void prepareDatabase() throws DAOException {
        MockDatabase.insertUsers();
        MockDatabase.insertUserGroups();
    }

    @Test
    public void shouldGetUserGroupSize() throws Exception {
        UserService userService = new UserService();
        User user = userService.find(1);
        boolean condition = user.getUserGroups().size() == 1;
        assertTrue("User groups size is incorrect!", condition);
    }
}

不幸的是它返回大小0.我可以在控制台中看到它将数据插入user和userGroup表。

模拟数据库的数据:

public static void insertUsers() throws DAOException {
    UserService userService = new UserService();

    User firstUser = new User();
    firstUser.setLogin("first");
    userService.save(firstUser);

    User secondUser = new User();
    secondUser.setLogin("second");
    userService.save(secondUser);
}

public static void insertUserGroups() throws DAOException {
    UserService userService = new UserService();
    UserGroupService userGroupService = new UserGroupService();

    UserGroup firstUserGroup = new UserGroup();
    firstUserGroup.setTitle("Admin");
    List<User> users = new ArrayList<>();
    users.add(userService.find(1));
    firstUserGroup.setUsers(users);
    userGroupService.save(firstUserGroup);

    UserGroup secondUserGroup = new UserGroup();
    secondUserGroup.setTitle("Random");
    userGroupService.save(secondUserGroup);
}

这是找到方法:

public User find(Integer id) throws DAOException {
    User result = (User) retrieveObject(User.class, id);
    if (result == null) {
        throw new DAOException("Object can not be found in database");
    }
    return result;
}

protected static Object retrieveObject(Class cls, Integer id) throws DAOException {
    try {
        Session session = Helper.getHibernateSession();
        if (session == null) {
            session = HibernateUtil.getSessionFactory().openSession();
            Object o = session.get(cls, id);
            session.close();
            return o;
        }
        return session.get(cls, id);
    } catch (HibernateException he) {
        throw new DAOException(he);
    }
}

在这里保存:

public User save(User user) throws DAOException {
    storeObject(user);
    return (User) retrieveObject(User.class, user.getId());
}

protected static void storeObject(Object object) throws DAOException {
    try {
        Session session = Helper.getHibernateSession();
        session.saveOrUpdate(object);
        session.flush();
        session.beginTransaction().commit();
    } catch (HibernateException he) {
        rollback();
        throw new DAOException(he);
    }
}

它看起来将数据保存到用户表和userGroup表,但它不会将数据保存到user_x_userGroup表。什么可能导致这个问题?

3 个答案:

答案 0 :(得分:1)

您需要在您的关系中添加casacade类型:

@ManyToMany(cascade = CascadeType.ALL)

答案 1 :(得分:1)

您不会将您持久存在的UserGroup实例设置为该关系所有者的实体。

UserGroup中声明:

@ManyToMany(mappedBy = "userGroups")
private List<User> users;

这意味着双向关系的所有者方是User实体。

在您的实际代码中,所有者方(User)没有引用您要保留的UserGroup实体,因此UserGroup实体将被保留,但它会与您在users中设置的UserGroup字段无关。

所以只需适当设置它就可以了:

UserGroup firstUserGroup = new UserGroup();
firstUserGroup.setTitle("Admin");
List<User> users = new ArrayList<>();
// change
User user = userService.find(1);
List<UserGroup> groups = new ArrayList<>();
groups.add(firstUserGroup);
user.setUserGroups(groups);
// end change
users.add(user);          
firstUserGroup.setUsers(users);
userGroupService.save(firstUserGroup);
...

答案 2 :(得分:1)

更改User.java和UserGroup.java类关系,如下所示,并尝试它的工作原理。

User.java

@ManyToMany(targetEntity = User.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "user_x_userGroup",
    joinColumns = 
            @JoinColumn(name = "user_id",foreignKey = @ForeignKey(name = "FK_user_x_userGroup_user_id")),inverseJoinColumns = 
            @JoinColumn( name = "userGroup_id",foreignKey = @ForeignKey(name = "FK_user_x_userGroup_userGroup_id")))
private List<UserGroup> userGroups;

UserGroup.java

@ManyToMany(targetEntity = UserGroup.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
joinColumns = 
            @JoinColumn(name ="userGroup_id",foreignKey = @ForeignKey(name = "FK_user_x_userGroup_userGroup_id")),inverseJoinColumns = 
            @JoinColumn( name = "user_id",foreignKey = @ForeignKey(name = "FK_user_x_userGroup_user_id")))
private List<User> users;