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