【问题标题】:detached entity passed to persist Spring JPA分离实体传递给持久 Spring JPA
【发布时间】:2017-10-23 10:38:09
【问题描述】:

在保存数据时出现“传递给持久化的分离实体:com.technople.domain.Role;嵌套异常是 org.hibernate.PersistentObjectException:传递给持久化的分离实体:com.technople.domain.Role”的错误

RolePrivilegesX 代码片段

@Entity
@Table(name="role_privileges_X")
@NamedQuery(name="RolePrivilegesX.findAll", query="SELECT r FROM RolePrivilegesX r")
public class RolePrivilegesX extends AbstractBaseEntity{
    @ManyToOne
    @JoinColumn(name = "role_id")
    private Role role;
    @ManyToOne
    @JoinColumn(name = "company_id")
    private Company company;
    private String privileges;

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

角色片段

@Entity
@Table(name = "role")
public class Role extends AbstractBaseEntity {
      @OneToMany(mappedBy = "role", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    private List<RolePrivilegesX> rolePrivilegesXs;
   public void setRolePrivilegesXs(List<RolePrivilegesX> rolePrivilegesXs) {
        this.rolePrivilegesXs = rolePrivilegesXs;
    }

    public void setRecordAssignment(RecordsAssignment recordAssignment) {
        this.recordAssignment = recordAssignment;
    }

    public RolePrivilegesX addRolePrivilegesX(RolePrivilegesX rolePrivilegesX) {
        if (getRolePrivilegesXs() == null) {
            setRolePrivilegesXs(new ArrayList<>());
        }
        getRolePrivilegesXs().add(rolePrivilegesX);
        rolePrivilegesX.setRole(this);

        return rolePrivilegesX;
    }

    public RolePrivilegesX removeRolePrivilegesX(RolePrivilegesX rolePrivilegesX) {
        List<RolePrivilegesX> rolePrivilegesXs = getRolePrivilegesXs();
        if (null == rolePrivilegesXs) {
            rolePrivilegesXs = Lists.newArrayList();
        }
        rolePrivilegesXs.remove(rolePrivilegesX);
        rolePrivilegesX.setRole(null);;

        return rolePrivilegesX;
    }
    }

AbstractBaseEntity 代码片段

@MappedSuperclass
public class AbstractBaseEntity {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
}

RoleServiceImpl 代码 sn-ps

@Override
    @Transactional(readOnly = false)
    public RoleForm saveOrUpdate(RoleForm roleForm) {
        Company company = loggedInCompany();
        Employee loggedInEmployee = loggedInEmployee();
        Role role = null;
        if (null != roleForm.getRoleId()) {
            role = roleRepository.findOne(roleForm.getRoleId());
        }
        if (null == role) {
            role = new Role();
            role = assignNewRolePrivileges(roleForm, role);
        } else {
            List<RolePrivilegesX> rolePrivilegesXs = role.getRolePrivilegesXs();
            if (null == rolePrivilegesXs || rolePrivilegesXs.isEmpty()) {
                role = assignNewRolePrivileges(roleForm, role);
            } else {
                rolePrivilegesXs.forEach(rolePrivilegesX -> rolePrivilegesX.setDeleted(Boolean.TRUE));
                RolePrivilegesX rolePrivilegesX = createNewRolePrivileges(roleForm, role);
                rolePrivilegesXs.add(rolePrivilegesX);
            }
        }
        role.setCompany(company);
        role.setCreatedBy(loggedInEmployee.getName());
        role.setDeleted(Boolean.FALSE);
        role.setName(roleForm.getName());
        role.setParent(findRole(roleForm.getReportsTo()));
        Role savedRoles = roleRepository.save(role);
        return new RoleForm(savedRoles);
    }

角色存储库片段

package com.technople.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.technople.domain.Company;
import com.technople.domain.Role;

public interface RoleRepository extends JpaRepository<Role, Long>{
    List<Role> findByCompanyAndDeleted(Company company, Boolean deleted);
}

我已经经历了很多类似的问题,但这并没有解决我的问题。请建议我在这方面做错了什么。

【问题讨论】:

  • 你可以发布你的 roleRepository.save 方法
  • @Tom 我已经更新了问题
  • 你在createNewRolePrivileges(roleForm, role);方法中使用newoperator吗? (正如方法名称所假设的)

标签: spring hibernate spring-data-jpa


【解决方案1】:

我觉得问题很可能出在级联类型上,您需要使用CascadeType.MERGE 而不是CascaCadeType.ALL

【讨论】:

  • 将级联类型从 ALL 更改为 MERGE 可解决问题。但是在我的情况下,嵌套对象没有分配 Id 列(它们是自动生成注释)!
  • 我还尝试将级联类型保持为 ALL 并在保存之前使用实体管理器进行刷新,但仍然出现相同的错误。不知道为什么刷新对象不能解决问题!
【解决方案2】:

没关系。当我在双向关系上正确设置级联类型时,我的问题得到了解决。早些时候我只在父级上设置了级联类型,在子级上设置后一切都按预期工作。

谢谢

【讨论】:

    【解决方案3】:

    您可以将级联类型设置为Persist 而不是All。 这将解决问题,因为您已经使用 transactional 注释了函数

    【讨论】:

      猜你喜欢
      • 2013-06-26
      • 2017-10-21
      • 1970-01-01
      • 2018-01-05
      • 2015-12-26
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      相关资源
      最近更新 更多