具有相同标识符的不同对象已与会话关联

时间:2015-09-09 12:55:38

标签: java spring hibernate

我在尝试更新“照片”时遇到错误:

  Photo photo = photoRepository.findById(id);
  List<Photo> photos = user.getPhotos();
  user.setPhotos(photos.add(photo));      
  userRepository.update(user);

显示以下错误:

  Different object with same identifier was already associated with the session

看来,具有相同标识符的不同对象(第一行:第一行中的照片,第二行:user.getPhotos()中的照片)。

所以,我无法更新我的用户。 我怎么能避免这个错误?

userRepository:

tx = session.beginTransaction();
user = (User) session.get(User.class, id);
session.getTransaction().commit();

1 个答案:

答案 0 :(得分:0)

您的代码存在缺陷,在ORM世界中管理双向关系时,您绝不允许对内部状态进行外部修改。目前,您正在使用一种服务方法,即从用户中提取照片列表并添加新照片。有了这个你只设置关系的一面。您还应该在setUser对象上调用Photo

Photo photo = photoRepository.findById(id);
List<Photo> photos = user.getPhotos();
photo.setUser(user);
user.setPhotos(photos.add(photo));      
userRepository.update(user);

但是这段代码容易出错,应该在User旁边的setPhotos对象内,你不应该允许public class User { public Set<Photo> getPhotos() { // Unmodifiable to protect internal state. return Collections.unmodifiableSet(this.photos); } // No setPhotos! public void addPhoto(Photo photo) { photo.setUser(this); this.photos.add(photo); } } 被调用,因为这可能会破坏所有正确的关系。

Photo

假设您的UsersetUser位于同一个包中,public可以是包可见的(即{{1}上没有protectedsetUser }} 方法)。

现在,您可以在代码中执行

Photo photo = photoRepository.findById(id);
user.addPhoto(photo);
userRepository.update(user);

无需使其更复杂,添加照片的逻辑现在已经很好地封装和测试。