简体   繁体   中英

JPA One To Many Relationship Persistence Bug

I've got a really weird problem with a bi-directional relationship in jpa (hibernate implementation). A User is based in one Region, and a Region can contain many Users.

So...relationship is as follows:

Region object:

@OneToMany(mappedBy = "region", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public Set<User> getUsers() {
  return users;
}
public void setUsers(Set<User> users) {
  this.users = users;
}

User object:

@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinColumn(name = "region_fk")
public Region getRegion() {
  return region;
}
public void setRegion(Region region) {
  this.region = region;
}

So, the relationship as you can see above is Lazy on the region side, ie, I don't want the region to eager load all the users. Therefore, I have the following code within my DAO layer to add a user to an existing user to an existing region object...

public User setRegionForUser(String username, Long regionId){
  Region r = (Region) this.get(Region.class, regionId);
  User u = (User) this.get(User.class, username);
  u.setRegion(r);
  Set<User> users = r.getUsers();
  users.add(u);
  System.out.println("The number of users in the set is: "+users.size());
  r.setUsers(users);
  this.update(r);
  return (User)this.update(u);
}

The problem is, when I run a little unit test to add 5 users to my region object, I see that the region.getUsers() set always stays stuck at 1 object...somehow the set isn't getting added to.

My unit test code is as follows:

public void setUp(){
  System.out.println("calling setup method");
  Region r = (Region)ManagerFactory.getCountryAndRegionManager().get(Region.class, Long.valueOf("2"));
  for(int i = 0; i<loop; i++){
    User u = new User();
    u.setUsername("username_"+i);
    ManagerFactory.getUserManager().update(u);
    ManagerFactory.getUserManager().setRegionForUser("username_"+i, Long.valueOf("2"));
  }
}

public void tearDown(){
  System.out.println("calling teardown method");
  for(int i = 0; i<loop; i++){
    ManagerFactory.getUserManager().deleteUser("username_"+i);
  }
}

public void testGetUsersForRegion(){
  Set<User> totalUsers = ManagerFactory.getCountryAndRegionManager().getUsersInRegion(Long.valueOf("2"));
  System.out.println("Expecting 5, got: "+totalUsers.size());
  this.assertEquals(5, totalUsers.size());
}

So the test keeps failing saying there is only 1 user instead of the expected 5. Any ideas what I'm doing wrong?

thanks very much, Brian

What is the implementation for update(r) ? Are you remembering to commit?

What is the implementation of hashcode and equald in User? Maybe all your users are considered the same in the Set so only one gets saved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM