I am having a problem with many, many associations in my save level. My scenario is as follows:
A user can have multiple roles, and a role can have multiple users. During the tests, I came across strange behavior. I created a role object and several custom objects. A role has been set for each of the users. After that, users were saved using the DAO. Then one of the users logs in to check if he received the role that was transferred to him before saving the user object. A call to getRoles() for the user indicates that the role was installed correctly.
To check if the reverse direction is working, the role object is loaded from the database using the DAO role. But calling getUsers() on the role object simply returns an empty set, although it should contain all users with this role.
I double checked the database table, but everything seems to be correct. The user, role, and user_role table were populated correctly.
So why does the role object not contain a user?
I use Hibernate and Spring with the following classes.
User class
@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>(); ... }
Role class
@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>(); ... }
For testing, I use the following code in the JUnit test class.
@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());
UPDATE
Sorry, I forgot to mention one thing. When I tested the code, of course, I did not mark many, many associations twice in each class file. Instead, I used option 1 or option 2 in each class file.