我已经阅读了很多关于类似问题的文章和答案,但我仍然无法理解。
这是我的父类:
@Entity
@Table(name = "users")
public class User implements Serializable, Annotation {
@Id
@GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY)
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true)
protected String uuid;
@Column(name = "username")
protected String username;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.user", cascade = CascadeType.ALL)
private Set<UserItem> userItems;
}
在这里我们可以看到两组 - 项目和用户的朋友。
UserItemId 类的示例:
@Entity
@Table(name = "user_item")
@AssociationOverrides({
@AssociationOverride(name = "pk.user",
joinColumns = @JoinColumn(name = "user_uuid")),
@AssociationOverride(name = "pk.ItemShop",
joinColumns = @JoinColumn(name = "item_shop_uuid")) })
public class UserItem implements Serializable {
@EmbeddedId
protected UserItemId pk = new UserItemId();
@Transient
public User getUser() {
return getPk().getUser();
}
public void setUser(User user) {
getPk().setUser(User);
}
@Transient
public ItemShop getItemShop() {
return getPk().getItemShop();
}
public void setItemShop(ItemShop ItemShop) {
getPk().setItemShop(ItemShop);
}
}
现在我正在尝试向用户添加新项目:
/*
'user' in this code i got from SecurityContext in controller
and I give it as parameter from controller to method (service layer) which can add new Item to user.
So user it is entity which already exists in database - it is logged user
*/
UserItem userItem = new UserItem();
userItem.setUser(user);
userItem.setItemShop(ItemShop);
user.getUserItems().add(userItem);
session.saveOrUpdate(user);
但我得到一个错误:
org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联
我知道主要问题出在 CascadeTypes - ALL 它不是最好的变体,因为休眠不能做我想要的 - 了解 User 是一个持久对象,只需添加到持久新项目并将其保存到数据库。所以我想问你,当我有父类(用户)和子类(项目)并且我想添加新项目并从父级删除项目并将其保存到数据库时,在这种情况下获胜的最佳做法是什么。确实我找到了工作方法(使用迭代器),但我知道在高负载项目中,它是此类操作的最糟糕的变体循环。我真的很想为这种情况找到最佳实践。
问题更新: 我犯了错误。当我调用执行将子元素添加到集合的代码时(上面的代码)-一切都很好-在数据库和实体中添加了子元素,但是当我尝试删除子元素时:
Set<UserItem> userItems = user.getUserItems();
UserItem userItem = userDAO.findUserItem(user, itemShop);
userItems.remove(userItem);
session.saveOrUpdate(user);
session.flush();
然后我得到了异常:
org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联
另一个更新:
经过大量实验后,我得到了添加项目的工作代码:
UserItem userItem = new UserItem();
userItem.setUser(user);
userItem.setItemShop(ItemShop);
user.getUserItems().add(userItem);
session.saveOrUpdate(user);
它是服务层中向用户添加项目的方法代码。它正在工作。而且我有一半工作代码可以从用户那里删除项目:
Set<UserItem> userItems = user.getuserItems();
UserItem userItem = UserDAO.findUserItem(user, itemShop);
userItems.remove(userItem);
userDAO.merge(user);
它不是正常工作的代码。我们有一个情况 - 用户有 3 个项目。我删除了一项 - 一切都很好。后来我试图再删除一项,hibernate 告诉我:
ObjectNotFoundException:不存在具有给定标识符的行
这意味着在缓存中仍然有 3 个项目 - 我首先删除的一个 - 仍然在缓存中,并且休眠尝试将其添加到数据库中 - 但它被删除了。
我又多了一个想法,可以帮助我们回答这个问题。对象用户 - 我试图删除孩子 - 它是从 SecurityContext 登录的用户 - 我从控制器得到它 - 控制器有注释用户从安全获得的位置。因此,hibernate 已经在缓存中记录了用户(用户对象)。有任何想法吗?