我正在尝试使用jpa更新父实体和子实体(随父实体一起提供)。我试过很多方法,但都做不到。它给了我以下的错误。
javax.persistence.entityexistsexception:具有相同标识符值的不同对象已与会话联系人关联(6)
以下是实体,
父->user.java
@Entity
public class User extends Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_generator")
@SequenceGenerator(name = "seq_generator", sequenceName = "seq_users", initialValue = 1, allocationSize = 1)
private Long id;
private String firstName;
private String lastName;
private String email;
private String password;
private String street;
private String city;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "userContact")
private Contact contact;
}
子->contact.java
@Entity
public class Contact extends Serializable {
private static final long serialVersionUID = 1L;
@Getter(value = AccessLevel.NONE)
@Setter(value = AccessLevel.NONE)
@Id
@Column(insertable = false, updatable = false)
private Long id;
@MapsId
@OneToOne
@JoinColumn(name = "id", nullable = false)
private User userContact;
private String phone;
}
在我的service.java中,我是这样更新的,
@Override
@Transactional
public User update(Long id, User user) {
Optional<User> curUser = userRepo.findById(id);
user.setId(curUser.get().getId());
user.setStreet(curUser.get().getStreet());
user.setCity(curUser.get().getCity());
Contact contact = user.getContact();
contact.setUserContact(user);
user.setContact(contact);
return userRepo.save(user);
}
更新json负载是这样的,
{
"firstName": "FirstName",
"lastName": "LastName",
"email": "Email",
"password": "Password",
"contact": {
"phone": "0123456789"
}
}
为什么我不能马上更新?插入工作正常,但此更新不工作。我做错什么了?如果有人能帮我,我真的很感激。提前谢谢。
这是我尝试的新方法,
@Override
@Transactional
public User update(Long id, User user) {
Optional<User> curUser = userRepo.findById(id);
curUser.setFirstName(user.getFirstName());
curUser.setlastName(user.getLastName());
curUser.setEmail(user.getEmail());
curUser.setPassword(user.getPassword());
Contact contact = user.getContact();
contact.setUserContact(curUser);
curUser.setContact(contact);
return userRepo.save(curUser);
}
1条答案
按热度按时间zlhcx6iw1#
因为在持久性上下文中有两次表示相同的用户(即相同的id)。
此行加载用户
curUser
在持久性上下文中。这条线使
user
同一个用户的id,但它是一个不同的瞬间。最后这一行试图添加
user
到持久性上下文。这将导致两个示例被附加到持久性上下文,同时用相同的id表示相同的用户,这将导致不一致的状态,因为jpa不知道要持久化哪个版本。因此,这是被禁止的,并抛出你看到的异常。
在你的情况下
到
应该会成功的。
关于您的意见:
引用的对象也存在同样的问题。您必须确保:要么加载实体并更改其属性,要么不加载实体,而不是直接或间接地通过引用加载实体,并保存从您的请求构造的分离实体。
如果加载一个实体,然后尝试保存它的分离示例,则会出现这种错误。