Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有相同标识符的不同对象已与会话关联_Java_Spring_Hibernate - Fatal编程技术网

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

Java 具有相同标识符的不同对象已与会话关联,java,spring,hibernate,Java,Spring,Hibernate,尝试更新“照片”时出现错误: Photo photo = photoRepository.findById(id); List<Photo> photos = user.getPhotos(); user.setPhotos(photos.add(photo)); userRepository.update(user); 看起来,不同的对象具有相同的标识符(第一行:photo,第二行:photo,inside user.getPhotos()) 因此,我

尝试更新“照片”时出现错误:

  Photo photo = photoRepository.findById(id);
  List<Photo> photos = user.getPhotos();
  user.setPhotos(photos.add(photo));      
  userRepository.update(user);
看起来,不同的对象具有相同的标识符(第一行:photo,第二行:photo,inside user.getPhotos())

因此,我无法更新我的用户。 如何避免这个错误

用户存储库:

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

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

Photo photo = photoRepository.findById(id);
List<Photo> photos = user.getPhotos();
photo.setUser(user);
user.setPhotos(photos.add(photo));      
userRepository.update(user);
假设您的
照片
用户
在同一个包中,
设置用户
可以是可见的包(即
设置用户
方法上没有
公共
受保护

现在,在您的代码中,您可以简单地执行以下操作

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

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

您正在使用Spring,为什么要手动管理事务?您永远不应该像那样获取集合并向其中添加对象。您正在泄漏内部状态。你应该在你的
User
上有一个
addPhoto
方法,该方法将
Photo
添加到集合中,并且假设它是双向关系,该方法也会执行
Photo.setUser
操作。对不起,我改为User.setPhotos(photos.add(Photo));我已经有photo.setUser()。手动管理交易是什么意思?你有其他的方法吗?哪一种更糟。。。您应该允许在外部设置内部集合,这对于托管集合尤其危险。您应该阅读注释。。。
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 photo = photoRepository.findById(id);
user.addPhoto(photo);
userRepository.update(user);