I use these two entities to create a new user and groups it associates:
@Entity
@Table(name="usertable")
@SuppressWarnings("serial")
@Searchable
public class User implements Serializable {
@GeneratedValue(generator="userIdSeq")
@SequenceGenerator(name="userIdSeq", sequenceName="usertable_id_seq")
@SearchableId
@Id
int id;
@SearchableProperty
String userId; // 'Unique identifier. It is formed using this fashion: ''prefix:identifier''
String userName; // Name used to log in the application.
String email; // User's email
@ManyToMany
@JoinTable( name="usergroup",
joinColumns=@JoinColumn(name = "userid", referencedColumnName="userId"),
inverseJoinColumns=@JoinColumn(name = "groupid")
)
List<Group> groups;
...
}
// Group
@Entity
@Table(name="grouptable")
public class Group implements Serializable {
@Id
String groupId // Unique identifier for group.
String description // Brief text describing the group purposes.
@ManyToMany(mappedBy="groups")
@Cascade(SAVE_UPDATE)
List<User> users
....
}
On the database: usertable (id, userId, name) grouptable (id, description) usergroup(userid, groupid, groupkey)
It's very satisfying to add Group to list of groups, call save method on User and watch hibernate save the usergoup togehter. However, I have a big problem of hibernate automatically deleting entry from the usergroup table automatically when I retrieve the User after a save(User) operation.
Here is the test sequence that generation the deletion of usergroup
- save new user
- save new group
- And group to list in user
- save user
- get user from email
@Test @Transactional public void testGetUserByEmail(){ Session session = factory.getCurrentSession(); String email = "[email protected]"; User user = createUser(); user.setWeCanContact(true); user.setPartnersCanContact(false); user.setAgreedTerms(false); user.setReferer("Laura"); String groupId = "AARP"; String description = "Appletalk Address Resolution Protocol"; Group group1 = new Group(); group1.setGroupId(groupId); group1.setDescription(description); session.save(group1); session.flush(); user.getGroupLists().add(group1); session.saveOrUpdate(user); User testUser = userRepository.getUserByEmail(email); assertNotNull(testUser); assertEquals("It's not the correct email", email, testUser.getEmail()); }
private User createUser(){
Session session = factory.getCurrentSession();
String userId = "UB:2010";
String userPassword = "sarah";
String realName = "Sarah Silverman";
String email = "[email protected]";
User user = new User();
user.setUserId(userId);
user.setUserName(email);
user.setUserPassword(userPassword);
user.setRealName(realName);
user.setEmail(email);
List<Group> emptyGroupLists = new ArrayList<Group>();
user.setGroupLists(emptyGroupLists);
Group group = new Group();
group.setGroupId("ABC");
group.setDescription("A for apple");
user.getGroupLists().add(group);
session.save(group);
session.save(user);
session.flush();
return user;
}
// Repository Method to get user from email // // @NamedQuery(name="user.findByEmail", // query="SELECT u FROM User u " + // "LEFT JOIN FETCH u.groupLists " + // "WHERE upper(u.email) = :email") public User getUserByEmail(String email) { Session session = sessionFactory.getCurrentSession(); Query query = session.getNamedQuery("user.findByEmail"); query.setParameter("email", email.toUpperCase()); User user = (User)query.uniqueResult(); return user; }
Before executing step 5, usergroup with automatically removed like // SQL output
Hibernate:
delete
from
usergroup
where
userid=?
A few thing I to note; 1. userid is NOT the pk of user object. Would that be the problem? 2. The manyTomany mapping in usergroup mapped by userid and groupid 3. It happens not just in Test. It's in development too.
How can I stop the automatic deletion of usergroup. Usergroup is very important table and should not be deleted. Any help would be much appreciated. Thank you.