【问题标题】:JPA error while saving entity, object references an unsaved transient instance - save the transient instance before flushing保存实体时出现 JPA 错误,对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例
【发布时间】:2023-04-05 01:31:01
【问题描述】:

我收到以下错误,

对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例:Nominee;嵌套异常是 java.lang.IllegalStateException: org.hibernate.TransientObjectException: 对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例:Nominee 对象引用未保存的瞬态实例 - 保存瞬态 刷新前的实例

在 org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381) 在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:227) 在 org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521) 在 org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 在 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) 在 com.sun.proxy.$Proxy180.save(未知来源)

我有 2 个实体类 Employee.java (t_employee) 和 Nominee.java(t_nominee),其中一个员工可以有很多被提名人,所以我创建了一个名为 ta_empl_nom 的关联表(我想要作为关联表本身,因为稍后我可以选择将其他员工与现有被提名人联系起来)

所以在这里当我获取员工对象时,我想要以键作为被提名人姓名和对象被提名人本身的被提名人对象的映射。我成功地得到了对象。

但保存时出现问题。当我保存员工对象时,它也应该保存其被提名人的详细信息。

这里是实体类 Employee.java

@Entity
@Table( name = "t_employee" )
public class Employee {
    @Id
    @GeneratedValue( strategy = GenerationType.AUTO )
    private long id;
    @Column( name = "name" )
    private String name;

@ElementCollection( fetch = FetchType.LAZY )
    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable( name = "ta_emp_nom", joinColumns = @JoinColumn( name = "employee" ), inverseJoinColumns = @JoinColumn( name = "nominee" ) )
    @MapKey( name = "name" )
    private Map<String, Nominee> nomineeMap;

//getters and setters

}

这里是 Nominee 实体类 Nominee.java

@Entity
@Table( name = "t_nominee" )
public class Nominee {

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

    @Column( name = "name" )
    private String name;

// other fields, getters, and setter for them below
}

这是我的服务层

Employee emp = new Employee();
emp.setName("Rahul");
Map<String,Nominee> nomineeMap = new HashMap<>();
Nominee nom1 = new Nominee();
nom1.setName("nom1");
Nominee nom2 = new Nominee();
nom1.setName("nom2");
nomineeMap.put(nom1.getName(), nom1);
nomineeMap.put(nom2.getName(), nom2);
emp.setNominee(nomineeMap);
employeeRepository.save(emp); //error here while saving this emp obj

我在保存时收到上述错误消息。

【问题讨论】:

标签: java spring hibernate spring-mvc jpa


【解决方案1】:

当您应该在持久性中创建记录时,您可能正在更新它,因为它是新的。因此,请使用您的实体管理器在对象及其拥有的任何外键中执行 persist

【讨论】:

    【解决方案2】:

    您的答案已在异常的第一行中提供。您可能只是在会话中保存了对象,但没有提交牵引力。所有其他部分都是正确的,只需提交事务。确保您已在休眠配置文件中映射了两个实体类,并且所有配置都已正确完成。现在你的持久化方法应该是这样的。 [我在这里创建了一个 SessionFactory 对象,但是你应该在整个项目中为一个数据库创建一个对象。]

        SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        Session session = null;
        Transaction transaction = null;
        try {
    
            session = sessionFactory.openSession();
            transaction = session.beginTransaction();
            Employee emp = new Employee();
            emp.setName("Rahul");
            Map<String, Nominee> nomineeMap = new HashMap<>();
            Nominee nom1 = new Nominee();
            nom1.setName("nom1");
            Nominee nom2 = new Nominee();
            nom1.setName("nom2");
            nomineeMap.put(nom1.getName(), nom1);
            nomineeMap.put(nom2.getName(), nom2);
            emp.setNomineeMap(nomineeMap);
            session.save(emp);
            transaction.commit();
        } catch (Exception e) {
    
            if (transaction != null) {
                transaction.rollback();
            }
        } finally {
    
            session.close();
            sessionFactory.close();
        }
    

    【讨论】:

      猜你喜欢
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 2012-02-27
      • 2019-01-14
      • 2012-03-21
      • 2019-10-31
      • 2018-04-01
      相关资源
      最近更新 更多