有没有办法将分离的对象传递给JPA持久化? (传递给持久化的分离实体)

时间:2012-12-12 08:51:22

标签: java hibernate jpa entitymanager

我有2个实体:AccountAccountRole

public class Account {
   private AccountRole accountRole;

   @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
   public AccountRole getAccountRole() {
      return accountRole;
   }

public class AccountRole {
    private Collection<Account> accounts = new ArrayList<Account>();

    @OneToMany(mappedBy = "accountRole", fetch = FetchType.EAGER)
    public Collection<Account> getAccounts() {
         return accounts;
    }

当我从数据库中获取accountRole并尝试保留Account时出现问题。 此时我刚刚创建了我的帐户,角色已经存在于db。

AccountRole role = accountService.getRoleFromDatabase(AccountRoles.ROLE_USER);
account.setAccountRole(role);

//setting both ways, as suggested
public void setAccountRole(AccountRole accountRole) {
    accountRole.addAccount(this);
    this.accountRole = accountRole;
}

entityManager.persist(account); // finally in my DAO

我读到了这个:JPA/Hibernate: detached entity passed to persist 我理解的是,我必须从两个方向设置实体值,以便我在我的设置器中执行的操作。

仍然出现错误。

 org.hibernate.PersistentObjectException: detached entity passed to persist: foo.bar.pojo.AccountRole

3 个答案:

答案 0 :(得分:16)

只需替换

即可
entityManager.persist(account);

使用:

entityManager.merge(account);

并允许合并级联:

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
public AccountRole getAccountRole() {
    return accountRole;
}

因为合并这样做:

  

如果您的实体是新实体,则它与persist()相同。   但是,如果您的实体已经存在,它将更新它。

答案 1 :(得分:3)

看起来您在处理过程中会离开事务,因此accountRole会被分离,或者由于其他原因而已经分离。

在致电entityManager.merge(accountRole)之前致电entityManager.persist(account)应修复此问题。

编辑:不幸的是,如果您无法确定数据库中是否已存在accountRole,则必须通过查询来检查它。如果存在 - 合并,如果不存在 - 继续。这确实很麻烦,但我还没有看到更好的解决方法。

EDIT2:您传递给merge方法的实体将保持分离 - 管理实体将由merge返回,因此您需要先合并,然后在{上设置参考{1}}到account的返回值。

答案 2 :(得分:0)

您无法传递数据实体来持久化,这是不可能的。但是您不需要。

您想独立于Account(已经被持久保存)而持久地AccountRole。为此,只需从子实体中的@ManyToOne删除级联(在这种情况下为Account

public class Account {
    private AccountRole accountRole;

    @ManyToOne // no cascading here!
    public AccountRole getAccountRole() {
        return accountRole;
    }

在这里查看我的解释,原因:https://stackoverflow.com/a/54271569/522578