Java UnuniqueObjectException和IdentifierGenerationException-无法更新表

Java UnuniqueObjectException和IdentifierGenerationException-无法更新表,java,hibernate,spring-mvc,Java,Hibernate,Spring Mvc,我使用MySQL、Hibernate、JPA和Spring,我的问题是无法一对一地更新关联的子表;我在用一种外交策略 当我使用saveOrUpdate并调用first time方法时,我可以将实体保存到数据库中,但当我再次调用它(update)时,我会得到UnuniqueObjectException。所以我将saveorupdate改为marge,但随后我得到了异常标识generationexception。我尝试了许多解决办法,但没有一个能解决我的问题 我的实体用户 @Entity @Tab

我使用MySQL、Hibernate、JPA和Spring,我的问题是无法一对一地更新关联的子表;我在用一种外交策略

当我使用saveOrUpdate并调用first time方法时,我可以将实体保存到数据库中,但当我再次调用它(update)时,我会得到UnuniqueObjectException。所以我将saveorupdate改为marge,但随后我得到了异常标识generationexception。我尝试了许多解决办法,但没有一个能解决我的问题

我的实体用户

@Entity
@Table(name = "user", uniqueConstraints = {
@UniqueConstraint(columnNames = {"login"})
})
@DynamicInsert
@DynamicUpdate
public class User implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private int user_id;

@OneToOne(mappedBy = "users")
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private UserInformation userInformation;

fields,getters,setters...
我的实体用户信息

@Entity
@Table(name = "user_information")
public class UserInformation implements Serializable{

@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "foreign", 
                  parameters = {@Parameter(name = "property", value = "users")})
@Column(name = "user_information_id", unique = true)
private int user_information_id;

@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User users;
fields,getters,setters....
userInformation.setUser(user);
  user.getUserInformation() //its not null
异常抛出时的方法

@Override
public void updateOrSaveUserInformation(int user_id,
        UserInformation userInformation) throws ObjectNotFoundException {
    Session session = this.sessionFactory.getCurrentSession();
    User user = (User) session.get(User.class, user_id);
    user.setUserInformation(userInformation);
    userInformation.setUser(user);
    session.merge(user);
}
我从我的控制器调用updateOrSaveUserInformation,在这里我使用modeldattributeuserinformation提交表单,并将表单中的用户信息传递给这个方法,我将用户信息保存在SessionAttribute中

当我调用这个方法时,我得到一个异常

org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one  
property [adrian.example.musicplayer.model.User.UserInformation.users]
我不知道在用户信息中设置用户的问题在哪里

@Entity
@Table(name = "user_information")
public class UserInformation implements Serializable{

@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "foreign", 
                  parameters = {@Parameter(name = "property", value = "users")})
@Column(name = "user_information_id", unique = true)
private int user_information_id;

@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User users;
fields,getters,setters....
userInformation.setUser(user);
  user.getUserInformation() //its not null
当我使用用户saveOrUpdate时,我得到异常

org.springframework.dao.DuplicateKeyException: A different object with the same identifier 
value was already associated with the session : 
[adrian.example.musicplayer.model.User.UserInformation#26]; nested exception is 
org.hibernate.NonUniqueObjectException: A different object with the same identifier value  
was 
already associated with the session :   
[adrian.example.musicplayer.model.User.UserInformation#26]
26号是来自用户的id

我还注意到,当我第二次调用updateOrSaveUserInformation时,我从UserInformation表中获取数据

@Entity
@Table(name = "user_information")
public class UserInformation implements Serializable{

@Id
@GeneratedValue(generator = "generator")
@GenericGenerator(name = "generator", strategy = "foreign", 
                  parameters = {@Parameter(name = "property", value = "users")})
@Column(name = "user_information_id", unique = true)
private int user_information_id;

@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User users;
fields,getters,setters....
userInformation.setUser(user);
  user.getUserInformation() //its not null

问题解释:

1) 当您通过以下方式获取
用户
详细信息时:

User user = (User) session.get(User.class, user_id);
然后Hibernate也加载
UserInformation
对象。因此在内存中Hibernate注意到,内存中有一个id为
26
UserInformation
类型的对象

2) 现在,当您只有这行代码时:

user.setUserInformation(userInformation);
userInformation.setUsers(user);
然后调用
session.saveOrUpdate(user)
,然后Hibernate抛出异常,如下所示:

 org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [.org.package...UserInformation.users]
 org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [org.package....UserInformation#26]
这是因为根据您的映射,
UserInformation
Id
映射为
foreign
用户的关键策略。因此,它尝试获取
users
(类型为
User
)属性,并尝试查找其
Id
,因为该
Id
null
,Hibernate无法将
Id
分配给
UserInformation
对象。这就是它说的原因:
试图从空属性用户分配id

3) 现在修复步骤2中的错误,如果您尝试再添加一行代码:

user.setUserInformation(userInformation);
userInformation.setUsers(user);
然后调用
会话。保存或更新(用户)
,然后hibernate再次抛出异常,如下所示:

 org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [.org.package...UserInformation.users]
 org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [org.package....UserInformation#26]
这是因为,您正在向自定义方法传递一个新的
UserInformation
对象,因此该对象没有任何
Id
。因此,当您调用
saveOrUpdate
时,hibernate会尝试从
users
属性中选择
Id
,该属性为
26
,然后尝试将其分配给新的
UserInformation
对象

最后,现在您有了两个
UserInformation
对象,它们的
Id
26
相同(根据步骤1和步骤3)。由于此原因,hibernate抛出了
ununiqueObjectException:具有相同标识符值的不同对象已与会话关联

解决方案:

要解决这些问题,可以执行以下操作:

User user = (User) session.get(User.class, user_id);
UserInformation info = user.getUserInformation();
info.setPropertyName(userInformation.getPropertyName());
session.saveOrUpdate(user);
只需获取
User
中可用的
UserInformation
对象,然后设置所有必需的属性,然后保存
User
对象