Spring JPA:插入新的Entity和Cascade分离的Reference

时间:2017-03-20 15:52:15

标签: java spring hibernate jpa orm

我有两个实体类组织和用户具有一对多的关系( Groovy代码为了简单起见!):

@Entity
class Organisation {
  @Id Long id
  String name
  @OneToMany
  List<User> users
}

@Entity 
class User {
  @Id Long id
  String username
  @ManyToOne(optional=false, cascade = CascadeType.Persist)
  Organisation organisation
}

当我使用新组织创建新用户时,一切正常:

def user = new User(organisation: new Organisation(...))

但是当我使用现有组织时,将其设置为用户的组织属性时会出现错误:

def user = new User(organisation: organisationRepository.findOne(orgId))
userRepo.save(user)

将导致:

  

org.hibernate.PersistentObjectException:传递给的分离实体   坚持:组织

我知道一个人不能在一个独立的实体上继续调用。但在那种情况下,由于我不会改变组织实体本身的任何内容,我认为hibernate会允许它。

我尝试将cascade = {CascadeType.Persist, CascadeType.Merge}放入 ManyToOne 注释中,但结果出现同样的错误。

我想用hibernate存档的东西是不可能的,还是我在某处有思考错误?

1 个答案:

答案 0 :(得分:1)

你正朝着正确的方向前进:

cascade = {CascadeType.Persist, CascadeType.Merge}

问题在于,当您仍然执行save操作时,持久性提供程序会尝试级联persist操作,因此它最终会尝试保留已经设置了@Id的组织实体并且是分离的。

您需要做的是执行merge而不是save

在这种情况下,新实体将被持久化,组织将被合并回持久化上下文,从而允许整个操作成功。

请记住,当您使用merge并希望之后对传递的实体执行操作时,您需要将结果分配给新变量并对其执行操作f.e。:

User mergedUser = userRepo.merge(user);

// operations on mergedUser from now on