Hibernate中的级联类型存储更新

nwo49xxi  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(176)

我正在使用带有JPA注解的Hibernate来进行关系Map。我的代码中有三个实体UserGroupUser_Group
UserGroup处于ManyToMany关系中。
User_Group是一种bridge table but with some additional fields。下面是修改后的Map代码。
用户

@Entity
@Table(name = "USERS")
public class User {

@OneToMany(mappedBy = "user")
private Set<UserGroup> userGroups
}

集团化

@Entity
@Table(name = "GROUPS")
public class Group {
@OneToMany(mappedBy = "group")
private Set<UserGroup> userGroups
}

用户组

@Entity
@Table(name = "USERS_GROUPS")
public class UserGroup {

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID")  
private User user;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "GROUP_ID")
private Group group;
}

当我将用户和组对象设置为用户组并保存它时。

User user = new User("tommy", "ymmot", "tommy@gmail.com");
Group group = new Group("Coders");

UserGroup userGroup = new UserGroup();
userGroup.setGroup(group);
userGroup.setUser(user);
userGroup.setActivated(true);
userGroup.setRegisteredDate(new Date());

session.save(userGroup);

一切都很顺利。使用CascadeType.ALL时,组对象和用户对象也会更新。但是当我删除UserGroup对象时。子对象也将被删除。
删除子对象是严格禁止的。
JPA中没有CascadeType.SAVE-UPDATE,它只执行保存或更新,而不执行删除。我如何实现这一点。
如果从Map中删除CascadeType.ALL,子对象不会更新&我需要更新它们。

c0vxltue

c0vxltue1#

SAVE_UPDATE用于SAVE()、UPDATE()和saveOrUpdate(),这是3个Hibernate专有方法。JPA只有persist()merge()。因此,如果您想在Hibernate专有方法上使用级联,则需要使用Hibernate专有注解。在本例中为Cascade
或者,您可以停止使用Hibernate会话,转而使用标准的JPA API。

huus2vyu

huus2vyu2#

CascadeType.ALL也包括CascadeType.REMOVE。解决方案是使用除CascadeType.REMOVE之外的所有CascadeType.*,如下所示:

@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}))

在您的用户组定义中。

nx7onnlm

nx7onnlm3#

当从子实体传播到父实体时,它几乎总是一种代码气味,应该反过来。
来自Cascading best practices
级联仅对父子关联有意义(父实体状态转换级联到其子实体)。从子到父的级联并不是很有用,通常是一种Map代码的味道。
来自Hibernate best practices
1.对于巨大的关系,避免级联移除大多数开发人员(包括我自己)在看到关系的CascadeType.REMOVE定义时都会有点紧张。它告诉Hibernate在删除此实体时也删除相关实体。人们总是担心相关实体也会对其某些关系使用CASCADE REMOVE,并且Hibernate可能会删除比预期更多的数据库记录。在我使用Hibernate的这么多年里,这种情况从未在我身上发生过,我也不认为这是一个真正的问题。但是层叠删除会让你很难理解如果你删除一个实体到底会发生什么。这是你应该永远避免的事情。如果你仔细看看Hibernate是如何删除相关实体的,你会发现另一个避免它的理由。Hibernate为每个相关实体执行2条SQL语句:1条SELECT语句从数据库获取实体,1条DELETE语句删除实体。如果只有1个或2个相关实体,这可能是可以的,但如果有大量相关实体,则会产生性能问题。

相关问题