当前位置: 首页 > 知识库问答 >
问题:

'org.hibernate.PersistentObjectException:已分离的实体传递给Persist:'

施招
2023-03-14

当试图在web应用程序上创建课程实体实例时,我们遇到以下错误。这是一个JHipster应用程序完整的错误日志,下面是,但主要错误是

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: edu.uwf.cen6030.domain.User; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: edu.uwf.cen6030.domain.User
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:319)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy183.save(Unknown Source)
        at edu.uwf.cen6030.web.rest.CourseResource.createCourse(CourseResource.java:68)

更新的代码

    @PostMapping("/courses")
    @Transactional()
    public ResponseEntity<Course> createCourse(@Valid @RequestBody Course course) throws URISyntaxException {
        log.debug("REST request to save Course : {}", course);
        if (course.getId() != null) {
            throw new BadRequestAlertException("A new course cannot already have an ID", ENTITY_NAME, "idexists");
        }
        if (Objects.isNull(course.getTeacher())) {
            throw new BadRequestAlertException("Invalid association value provided", ENTITY_NAME, "null");
        }

        Long userId = course.getTeacher().getId();
        userRepository.findById(userId).ifPresent(course::user);
        Course result = courseRepository.save(course);
        return ResponseEntity.created(new URI("/api/courses/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString()))
            .body(result);
    }

共有1个答案

颜志学
2023-03-14

错误的原因是,您从教师id加载了一个用户实体,然后将其附加到User字段,而它应该附加到教师ifPresent(Cource::teacher)以及类级别CourserSource或方法级别CourserSource#createCourse()@transactional注释。

因此,Hibernate抱怨教师实体没有加载到EntityManager中(即教师被分离),因为它来自JSON请求体,并且只包含一个ID。

我必须说,您附加的代码不能与git存储库中的代码一起编译。

以下修改后的代码通过CoursereSourceIT单元测试

    @PostMapping("/courses")
    @Transactional
    public ResponseEntity<Course> createCourse(@Valid @RequestBody Course course) throws URISyntaxException {
        log.debug("REST request to save Course : {}", course);
        if (course.getId() != null) {
            throw new BadRequestAlertException("A new course cannot already have an ID", ENTITY_NAME, "idexists");
        }
        if (Objects.isNull(course.getTeacher())) {
            throw new BadRequestAlertException("Invalid association value provided", ENTITY_NAME, "null");
        }
        Long userId = course.getTeacher().getId();
        userRepository.findById(userId).ifPresent(course::teacher);
        Course result = courseRepository.save(course);
        return ResponseEntity.created(new URI("/api/courses/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString()))
            .body(result);
    }
 类似资料: