我使用MySQL,Hibernate,JPA和Spring,我的问题是我无法一对一地更新子表;我使用外国策略。
当我使用saveOrUpdate并且我调用第一次方法时,我可以将实体保存到数据库但是当我再次调用它时(更新)我得到NonUniqueObjectException。所以我将saveorupdate更改为marge,但后来我得到异常IdentifierGenerationException。我尝试了很多解决方案,但没有一个能解决我的问题。
我的实体用户
@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....
异常抛出时的方法
@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,我使用ModelAttribute UserInformation提交表单,并将UserInformation从表单传递给此方法,我在SessionAttribute中保留Userinformation。
当我调用此方法时,我得到异常
org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one
property [adrian.example.musicplayer.model.User.UserInformation.users]
我不知道我在UserInformation中设置用户的问题在哪里
userInformation.setUser(user);
当我用户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
user.getUserInformation() //its not null
答案 0 :(得分:2)
问题说明:
1)当您使用以下方式获取User
详细信息时:
User user = (User) session.get(User.class, user_id);
然后Hibernate也加载你的UserInformation
对象。因此,在内存中,Hibernate注意到内存中可以使用id为UserInformation
的{{1}}类型的对象。
2)现在,只有 这行代码:
26
然后调用user.setUserInformation(userInformation);
然后Hibernate抛出异常:
session.saveOrUpdate(user)
这是因为根据您的映射, org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [.org.package...UserInformation.users]
的{{1}}与Id
的{{1}}关键策略进行了映射。因此它尝试获取UserInformation
(属于foreign
类型)属性并尝试查找其User
,因为此users
为User
,Hibernate是无法将Id
分配给您的Id
对象。所以这就是它说的原因:null
。
3)现在要修复第2步中的错误,如果您尝试再添加一行代码:
Id
然后调用UserInformation
,然后hibernate再次抛出异常:
attempted to assign id from null property users
这是因为您将新的userInformation.setUsers(user);
对象传递给自定义方法,因此该对象没有任何session.saveOrUpdate(user)
。因此,当您致电 org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [org.package....UserInformation#26]
时,hibernate会尝试从UserInformation
Id
属性中选择saveOrUpdate
,然后尝试将其分配给新的Id
对象
最后,现在您有两个users
个对象与26
相同UserInformation
(按照步骤1和步骤3)。因为这种休眠会引发UserInformation
<强>解决方案:强>
要解决这些问题,您可以执行以下操作:
Id
只需获取26
中的NonUniqueObjectException: A different object with the same identifier value was already associated with the session
对象,然后设置所有必需的属性,然后保存User user = (User) session.get(User.class, user_id);
UserInformation info = user.getUserInformation();
info.setPropertyName(userInformation.getPropertyName());
session.saveOrUpdate(user);
对象。