EntityManager obtained from JNDI lookup is already closed - java

For (Glassfish v2.1), two RuntimeExceptions from two separate requests from a session bean:
"org.hibernate.SessionException: Session is closed!"
org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1138)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:67)
[wrapped] javax.persistence.PersistenceException: org.hibernate.SessionException: Session is closed!
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:76)
"java.lang.IllegalStateException: EntityManager is closed"
java.lang.IllegalStateException: EntityManager is closed
at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:97)
at com.sun.enterprise.util.QueryWrapper.clearDelegates(QueryWrapper.java:460)
at com.sun.enterprise.util.QueryWrapper.getResultList(QueryWrapper.java:198)
Both of these EntityManagers were obtained via JNDI lookup (java:comp:/env/TargetSitePersistenceContext)
Using JTA (transaction-type attribute is not defined in persistence.xml).
& SQL Server 2008 w/ sqljdbc4.jar
The code just does the ff:
query = entityManager.createQuery();
query.getResultList();
And that's it. If I'm not mistaken, I believe the app container will handle open/commit/rollback/close, so we shouldn't have any entityManager.close().
What might have caused those two runtime exceptions?
When does GF actually open/close an EntityManager?
Is there any difference between:
an EntityManager obtained via JNDI lookup
via #PersistenceContext Injection? (So far not issues with this style)

All things being equal, a #PersistenceContext injection and a JNDI lookup should return the same EntityManager. So it might be a bug of GlassFish and you might want to reach for them. But make sure to give all the context like type of session bean used for injection, transaction or not etc etc.

Mark your bean with annotation #TransactionAttribute
#Stateless
#TransactionAttribute(TransactionAttributeType.MANDATORY)
public class Repo implements IRepo
{
container managed transaction is regulated by this parameter

Related

EJB with CMT when migrate from JBoss 7 to WildFly 9

I'm migrating my application from JBoss 7 to WildFly (v9.0.1) and it is not deployed because of bean transaction management error.
Caused by: javax.naming.NamingException: WFLYNAM0062: Failed to lookup env/com.component.eventmgt.EventServiceImpl/transaction [Root exception is java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction]
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:157)
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
... 90 more
Caused by: java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction
at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:319)
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:143)
... 95 more
Caused by: javax.naming.NameNotFoundException: UserTransaction [Root exception is java.lang.IllegalStateException: WFLYEJB0137: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction]
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:153)
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
... 96 more
Here is the EventServiceImpl class.
#Stateless
#Remote(EventService.class)
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventServiceImpl implements EventService {
/**
* Logger
*/
private static Logger log = LoggerFactory.getLogger(EventService.class);
private EventTableDAO eventDao;
#PersistenceContext(unitName = "SOMF-GT")
private EntityManager entityManager;
#Resource
private UserTransaction transaction;
public List<Map> loadEvents() throws EventsException {
Configuration configurationEntry = new Configuration();
try {
Map configuration = configurationService.getConfiguration();
if (configuration != null) {
eventDao = new EventTableDAO(Event.class, entityManager, transaction);
List<Map> eventsMapList = new ArrayList();
}
}
I know that if i changed the transaction management to BMT with #TransactionManagement(TransactionManagementType.BEAN) but then the following error emerge
WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
I want to know why we have to change this in the first place ?
Any information, please !
These changes rolled out in Wildfly 8 and were (as noted below) based on standardization of the global JNDI namespace in EJB 3.1.
From the Wildfly 8 Developer Guide:
EJB 3.1 introduced a standardized global JNDI namespace and a series of related namespaces that map to the various scopes of a Java EE application. The three JNDI namespaces used for portable JNDI lookups are java:global, java:module, and java:app. If you use JNDI lookups in your application, you will need to change them to follow the new standardized JNDI namespace convention.
To conform to the new portable JNDI namespace rules, you will need to review the JNDI namespace rules and modify the application code to follow these rules.
The guide further notes:
WildFly 8 has tightened up on JNDI namespace names to provide predictable and consistent rules for every name bound in the application server and to prevent future compatibility issues. This means you might run into issues with the current namespaces in your application if they don't follow the new rules.
Here's a snippet from the table showing Examples of JNDI mappings in previous releases and how they might look now specific to the UserTransaction:
Previous Namespace New Namespaces
------------------ --------------
java:comp/UserTransaction java:comp/UserTransaction (This will not be accessible for non EE threads, e.g. Threads your application directly creates)
java:comp/UserTransaction java:jboss/UserTransaction (Globally accessible, use this if java:comp/UserTransaction is not available)
Edit re: WFLYEJB0137:
This is theory-craft and may be worthless - let me know and I'll delete it. Java EE 6 Tutorial - Container-Managed Transactions says:
Enterprise beans that use container-managed transaction demarcation also must not use the javax.transaction.UserTransaction interface.
Further:
(Transaction) Required Attribute
If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.
The Required attribute is the implicit transaction attribute for all enterprise bean methods running with container-managed transaction demarcation. You typically do not set the Required attribute unless you need to override another transaction attribute. Because transaction attributes are declarative, you can easily change them later.
The exception message pretty much says it all:
WFLYEJB0137: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction
Your EJB is using container managed transaction (CMT) demarcation which does not inter-operate with bean managed transaction (BMT) demarcation wherein UserTransaction lies.
Regarding a switch to BMT and
WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
I found Transaction is required to perform this operation (either use a transaction or extended persistence context) which seems to indicate that the transaction is to be managed by you, as you noted in your comments #Marco. It appears that you have made the appropriate modification.

Facing issue in session with the upgrade of my application to Spring 4.1.9 and Hibernate 4.3.11

Facing issue in session with the upgrade of my application to Spring 4.1.9 and Hibernate 4.3.11..Logs are below:
[org.springframework.orm.hibernate4.HibernateTemplate] - <Could not retrieve pre-bound Hibernate session>
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:325)
at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
at org.springframework.orm.hibernate4.HibernateTemplate.findByCriteria(HibernateTemplate.java:1011)
at org.springframework.orm.hibernate4.HibernateTemplate.findByCriteria(HibernateTemplate.java:1003)
There may be below possible reason:
1) You need to put #Repository on class of DAO layer where you are trying to access session.
1) You need to put #Transactional below #Repository on class of DAO layer where you are trying to access session.
3) Your container is not able to find bean definition file where you have declared session factory and Transaction.

Transactional error while commiting

I am trying to solve this error in Payara41 server Java EE 7, this sample works on WildFly-9 Java 7 EE and on Glassfish-3.1 Java EE 6 (without #Transactional and #TransactionalManagement)
#Stateful
#Transactional //default TxType.REQUIRED
#TransactionManagement(TransactionManagementType.BEAN)
public class ImprovementDaoImpl extends AbstractBaseDaoClass implements ImprovementDao {
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
#PersistenceContext(unitName = "pu", type = PersistenceContextType.EXTENDED)
private EntityManager em;
#Resource
private UserTransaction tx;
...
}
Here's some stacktrace, what apperas after executing tx.flush();:
javax.transaction.TransactionalException: Managed bean with Transactional annotation and TxType of REQUIRED encountered exception during commit javax.transaction.RollbackException: Transaction marked for rollback.
(...)
Caused by: javax.transaction.RollbackException: Transaction marked for rollback.
So far I've tried to use interceptor and #TransactionAttribute, but none helped...
Thanks for any advice/help! :)
I know this is old, but hopefully this helps someone out there...
Question 21363423: Throwing an application exception causes TransactionalException says
You are throwing an exception from a method whose invocation will be
intercepted at runtime and additional logic wrapped around it:
transaction management;
exception handling.
Your exception cannot transparently jump over that logic, and the
specification (probably) says a TransactionalException will be thrown,
wrapping your original exception...
Question 18888572: How do you find out what Exception caused the CDI Transaction Rollback?
Shows how to use a CDI Interceptor to catch the exceptions. I can't tell from the limited info from the OP what his/her specific issue is, but when I received this exception I has to review the WebLogic server log and found the entry where it told me a unique contraint was violated.. Time to add some interceptors...

No session currently bound to execution context

I got below exception when I used session.getCurrentSession().
I have mentioned
hibernate.current_session_context_class: managed
org.hibernate.HibernateException: No session currently bound to execution context
at org.hibernate.context.internal.ManagedSessionContext.currentSession(ManagedSessionContext.java:75)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at io.dropwizard.hibernate.AbstractDAO.currentSession(AbstractDAO.java:36)
at io.dropwizard.hibernate.AbstractDAO.persist(AbstractDAO.java:149)
I use this with dropwizard. Can anyone help me to solve this?
If you are using Dropwizard Hibernate. You need to add #UnitOfWork annotation to your Resource method. More info within dropwizard manual, hibernate chapter.
Can you try with : session.openSession() - It tell hibernate to always opens a new session and you have to close once you are done with the operations. With session.getCurrentSession(), hibernate returns a session bound to a context that you don't need to close and only need to set the hibernate.current_session_context_class to thread.
You can also configure session with SpringSessionContext, if your application is Spring based.
Edit your hibernate-cfg.xml with below line:
hibernate.current_session_context_class=org.springframework.orm.hibernate3.SpringSessionContext
What above line will do?
Making session context class as "org.springframework.orm.hibernate3.SpringSessionContext
", Hibernate will assume it is executing inside of a Spring transactional context (i.e. through a Spring transactional aspect) and Spring will now manage your transaction for you. However if you call getCurrentSession() outside of such a context, Hibernate will throw an exception complaining that no Session is bound to the thread.

Accessing Hibernate Session from EJB using EntityManager

Is it possible to obtain the Hibernate Session object from the EntityManager? I want to access some hibernate specific API...
I already tried something like:
org.hibernate.Session hSession =
( (EntityManagerImpl) em.getDelegate() ).getSession();
but as soon as I invoke a method in the EJB I get "A system exception occurred during an invocation on EJB" with a NullPointerException
I use glassfish 3.0.1
Bozho and partenon are correct, but:
In JPA 2, the preferred mechanism is entityManager.unwrap(class)
HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class);
Session session = hem.getSession();
I think your exception is caused because you are trying to cast to an implementation class (perhaps you were dealing with a JDK proxy). Cast to an interface, and everything should be fine (in the JPA 2 version, no casting is needed).
From Hibernate EntityManager docs, the preferred way of doing it is:
Session session = entityManager.unwrap(Session.class);
As simple as:
Session session = (Session) em.getDelegate();
If your EntityManager is properly injected (using #PersistenceContext) and is not null, then the following should work:
org.hibernate.Session hSession = (Session) em.getDelegate();

Categories