] Hibernate Связь «многие-ко-многим»: левая коллекция содержит элементы, но правая часть пуста [

] [

] У меня возникла проблема с ассоциацией многие ко многим на уровне персистентности. Мой сценарий следующий: [

] [

] У пользователя может быть несколько ролей, и к роли может быть прикреплено несколько пользователей. Во время тестов я столкнулся со странным поведением. Я создал объект роли и несколько объектов пользователя. Каждому из пользователей была назначена роль. После этого пользователи были сохранены с помощью DAO. Затем загружается один из пользователей, чтобы проверить, получил ли он переданную ему роль перед сохранением объекта пользователя. Вызов [] getRoles () [] для пользователя показывает, что роль была установлена ​​правильно. [

] [

] Чтобы проверить, работает ли обратное направление, объект роли загружается из базы данных с помощью роли DAO. Но вызов [] getUsers () [] для объекта роли просто возвращает пустой набор, хотя он должен содержать всех пользователей с этой ролью. [

] [

] Я дважды проверил таблицу базы данных, но вроде все в порядке. Таблица User, role и user_role были заполнены правильно. [

] [

] [] Так почему же объект роли не содержит пользователя? [] [

] [

] Я использую Hibernate и Spring со следующими классами. [

] [

] [] Класс пользователя [] [

] [
@Entity
@Table
public class User extends BusinessObject {

    ... 

    // Option 1
    @ManyToMany(fetch = FetchType.LAZY,
                cascade = CascadeType.ALL,
                targetEntity=Role.class)
    @JoinTable(name= "user_role",
               joinColumns = {@JoinColumn(name="user_id")},
               inverseJoinColumns = {@JoinColumn(name="role_id")})  

    // Option 2
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name= "user_role", 
                   joinColumns = {@JoinColumn(name="user_id")},
           inverseJoinColumns = {@JoinColumn(name="role_id")})
    private Set<Role> roles = new HashSet<Role>();      

    ... 
}
] [

] [] Ролевой класс [] [

] [
@Entity
@Table
public class Role extends BusinessObject {
    ...

    // Option 1
    @ManyToMany(fetch = FetchType.LAZY, 
                cascade = CascadeType.ALL,
                mappedBy= "roles",
                targetEntity = User.class)

    // Option 2
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name= "user_role", 
                   joinColumns = {@JoinColumn(name="role_id")},
                   inverseJoinColumns = {@JoinColumn(name="user_id")})
    private Set<User> users = new HashSet<User>();          

    ... 
}
] [

] Для тестирования я использую следующий код в тестовом классе JUnit. [

] [
@Test
public void test(){     
    Transaction trans = sessionFactory.getCurrentSession().beginTransaction();

    Role userAdminRole = new Role();
    userAdminRole.setName(RoleName.USER_ADMIN);
    Role userRole = new Role();
    userRole.setName(RoleName.USER);

    User user1 = new User();
    user1.setEmail("user1@user.de");        
    user1.getRoles().add(userAdminRole);
    user1.getRoles().add(userRole);
    userDao.save(user1);

    User user2 = new User();
    user2.setEmail("user2@user.de");
    user2.getRoles().add(role);
    userDao.save(user2);

    User user3 = new User();
    user3.setEmail("user3@user.de");
    user3.getRoles().add(role);
    userDao.save(user3);            

    trans.commit();     

    User loadedUser = userDao.load(user1.getId());

            // Tests passes
    Assert.assertNotNull(loadedUser);
    Assert.assertEquals(user1, loadedUser);

    Set<Role> roles = loadedUser.getRoles();        

            // Tests passes
    Assert.assertEquals(2, roles.size());

    Role loadedUserAdminRole = roleDao.findByName(RoleName.USER_ADMIN);
    Set<User> users = loadedUserAdminRole.getUsers();

    // Test fails: Count is 0 instead of 3 !!!!!!!
    Assert.assertEquals(3, users.size());
}  
] [

] [] ОБНОВЛЕНИЕ [] [

] [

] Извините, я забыл упомянуть одну вещь. Когда я тестировал код, я, конечно, не отмечал ассоциацию многие ко многим дважды в каждом файле класса. Вместо этого я использовал либо вариант 1, либо вариант 2 в каждом файле класса. [

]
7
задан Flo 30 August 2011 в 22:25
поделиться