0
votes

I get following error,

object references an unsaved transient instance - save the transient instance before flushing: Nominee; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Nominee object references an unsaved transient instance - save the transient instance before flushing

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

I have 2 entity class Employee.java (t_employee) and Nominee.java(t_nominee) where an employee can have many numbers of nominee so I created an association table called ta_empl_nom (I wanted as association table itself, because later I may have option linking other employees to existing nominee)

so here when I fetch employee object, I want map of nominee object with key as nominee name and object nominee itself. I succeeded in getting the object.

but problem while saving. when I save employee object it should save its nominee details also.

Here is the entity classes 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

}

Here is the Nominee entity class 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
}

Here is my service layer

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

I am getting above error message while saving.

2
Try removing @OneToMany from Employee. See stackoverflow.com/questions/19428351/…Arthur

2 Answers

0
votes

Your answer is already provided in the first line of the exception. You probably just saved the object in session but didn't commit the traction. All other parts are correct just commit the transaction. Make sure that you have mapped both Entity classes in hibernate configuration file and all configuration is done properly. Now your persistence method should look like this. [I have created a SessionFactory object here but you should create only one object for a database in the whole project.]

    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();
    }
0
votes

You may be updating a record when you should be creating it in the persistence, because it is new. So, use your Entity Manager to do persist in the object and any foreign key it has.