【问题标题】:detached entity passed to persist in SpringBoot app传递到 Spring Boot 应用程序中的分离实体
【发布时间】:2019-01-23 02:22:14
【问题描述】:

我有一个基本的 SpringBoot 应用程序。使用 Spring Initializer、JPA、嵌入式 Tomcat、Thymeleaf 模板引擎和打包为可执行 JAR 文件我有这个实体: 我有一个公司的用户实体

@Entity
@Table(name="t_user")
public class User implements Serializable, UserDetails {



 @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Company company;

}

我创建了一个公司,我保存它,然后,我将它附加到用户:

user.setCompany(companyService.findAll().iterator().next());

但是当我保存用户时,我得到了这个错误:

detached entity passed to persist: com.elcor.backend.persistence.domain.backend.Company

这里是服务层的createUser方法

  @Transactional
    public User createUser(User user, Set<UserRole> userRoles) {

        User localUser = userRepository.findByEmail(user.getEmail());

        if (localUser != null) {
            LOG.info("User with username {} and email {} already exist. Nothing will be done. ",
                    user.getUsername(), user.getEmail());
        } else {

            String encryptedPassword = passwordEncoder.encode(user.getPassword());
            user.setPassword(encryptedPassword);

            //Plan plan = new Plan(plansEnum);
            // It makes sure the plans exist in the database
            //if (!planRepository.exists(plansEnum.getId())) {
             //   plan = planRepository.save(plan);
            //}

            //user.setPlan(plan);

            for (UserRole ur : userRoles) {
                roleRepository.save(ur.getRole());
            }

            user.getUserRoles().addAll(userRoles);


            localUser = userRepository.save(user);

        }

        return localUser;
    }

【问题讨论】:

  • 这个电话companyService.findAll().iterator().next()会给你一个id为的公司吗?
  • 是的,它返回一个带有 id 的公司
  • 可以在保存用户的地方添加语句吗?

标签: hibernate spring-mvc spring-boot spring-data-jpa spring-data


【解决方案1】:

我认为这是由于 cascade = CascadeType.ALL 具有持久性 它会尝试持久化一个已经脱离持久化上下文的实体。

所以尝试使用以下方法删除 CascadeType.PERSIST bu:

@OneToOne(cascade = { CascadeType.MERGE, CascadeType.REMOVE,
                      CascadeType.REFRESH, CascadeType.DETACH },
                      fetch = FetchType.EAGER)
private Company company;

【讨论】:

  • 能否请您使用用户映射线发布公司类
【解决方案2】:

问题在于级联。 如果您想使用 CascadeType.ALL,请不要单独保存公司和用户。 无论您尝试保存的公司实体都将其附加到用户实体,然后仅保存用户实体。 公司实体将自动持久化。

【讨论】:

    猜你喜欢
    • 2021-04-19
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    相关资源
    最近更新 更多