Reputation: 5043
I'm currently working on a project and I've encountered this error:
org.hibernate.TransientObjectException: object references an unsaved transient instance – save the transient instance before flushing
What happened: 1.) I have a session scope variable that I set after login, let's say SessionScopeVariableA.
2.) Then I have a page where I'm adding an entity, let's say EntityA.
3.) EntityA has a lazy field sessionScopeVariableA, so when I invoke the add method I have to set this variable.
entityA.setSessionScopeVariableA(sessionScopeVariableA);
em.persist(entityA);
4.) Note that SessionScopeVariableA is wrap in a session scope producer while the action is conversation scope.
5.) Whatever I do, I always end up with the transient error specified above.
Any idea?
Upvotes: 0
Views: 2621
Reputation: 5043
What solved this problem was managing the connection resource with CDI using solder. This is how we did this:
//qualifier for the tenant
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
public @interface CurrentTenant { }
//producer for the current tenant
@Produces
@Named("currentTenant")
@CurrentTenant
public Provider getCurrentTenant() { //.. }
//in a separate util class, define how you want to manage the connection resource (cdi)
@ExtensionManaged
@ConversationScoped
@Produces
@PersistenceUnit(unitName="myEM")
@MyEMJpa
private EntityManagerFactory em;
//interface for the connection resource
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
public @interface MyEMJpa { }
//inject entity manager in your service
@Inject
@MyEMJpa
protected EntityManager em;
//How to inject the current tenant
@Inject
@CurrentTenant
private Provider currentTenant;
Upvotes: 1