[maybe OT] JPA portable retrieval of Hibernate's Session from EntityManager

G

Giovanni Azua

hi,

I have the following dependencies: Hibernate, Hibernate-EntityManager and
OpenEJB latest implementation.

In one of my Container Managed Dao implementations I have the snippet below
which is the way to get the underlying Hibernate Session from the
EntityManager injected by the container (note the double level of
indirection 2x getDelegate). My question is how portable is this code? if I
wish to use now lets say JBoss or Oracle AS or WebSphere would this code
remain unchanged or there would be a different way?

Many thanks in advance,
Best regards,
Giovanni

//--------------------------------------------------------------------
@PersistenceContext(unitName = "movie-unit",
type = PersistenceContextType.EXTENDED)
public void
setEntityManager(EntityManager anEntityManager)
{
EntityManager myActualEntityManager = anEntityManager.
getDelegate();

Object myActualSession = myActualEntityManager.getDelegate();

return myActualSession;
}
 
A

Arved Sandstrom

Giovanni Azua said:
hi,

I have the following dependencies: Hibernate, Hibernate-EntityManager and
OpenEJB latest implementation.

In one of my Container Managed Dao implementations I have the snippet
below which is the way to get the underlying Hibernate Session from the
EntityManager injected by the container (note the double level of
indirection 2x getDelegate). My question is how portable is this code? if
I wish to use now lets say JBoss or Oracle AS or WebSphere would this code
remain unchanged or there would be a different way?

Many thanks in advance,
Best regards,
Giovanni

//--------------------------------------------------------------------
@PersistenceContext(unitName = "movie-unit",
type = PersistenceContextType.EXTENDED)
public void
setEntityManager(EntityManager anEntityManager)
{
EntityManager myActualEntityManager = anEntityManager.
getDelegate();

Object myActualSession = myActualEntityManager.getDelegate();

return myActualSession;
}

Apart from the fact that the above code is wrong (you're returning something
from a method declared to return nothing, and in any case it's not good
practise to be returning a session from a method that by name should be
setting something else), in principle any code you have that is specific to
Hibernate should work OK regardless of the server that it's used with. After
all, Hibernate is certified JPA-compatible, and the ability to extract
implementation-specific stuff is just Java code after all...nothing
mysterious about it.

Nomenclature aside, calling getDelegate() on an EntityManager will (by
specification) also work with Toplink. After that the methods (for obtaining
sessions or units of work) do differ.

AHS
 
G

Giovanni Azua

Hi Arved,

Arved Sandstrom said:
Apart from the fact that the above code is wrong (you're returning
something from a method declared to return nothing, and in any case it's
not good practise to be returning a session from a method that by name
should be setting something else), in principle any code you have that is
specific to
Indeed, sorry my bad, copy paste mistake.

what I actually have is a Movie EJB that lets the container inject the
EntityManager and passes it over to the super Generic DAO implementation, so
the Bean just:

- Let the container inject the appropriate EntityManager.
- Automatically exposes all IGenericDao facilities without having to
implement any.

<http://perfectjpattern.svn.sourcefo...integration/dao/jpa/MovieDao.java?view=markup>
//--------------------------------------------------------------------
@PersistenceContext(unitName = "movie-unit",
type = PersistenceContextType.EXTENDED)
public void
setEntityManager(EntityManager anEntityManager)
{
super(anEntityManager);
}

and then in the AbstractJPAGenericReadOnlyDao:

<http://perfectjpattern.svn.sourcefo...bstractJPAGenericReadOnlyDao.java?view=markup>
//------------------------------------------------------------------------
/**
* Sets the {@link EntityManager}, called from a managed EJB that exposes
* {@link IGenericReadOnlyDao} or {@link IGenericDao} remotely.
*
* @param anEntityManager The {@link EntityManager} to set
* @throws IllegalArgumentException 'anEntityManager' must not be null
*/
protected void
setEntityManager(EntityManager anEntityManager)
throws IllegalArgumentException
{
Validate.notNull(anEntityManager, "'anEntityManager' must not be null");

if (theEntityManager == null || theEntityManager != anEntityManager)
{
theEntityManager = anEntityManager;
theAdapterSession = new EntityManagerAdapter(anEntityManager).
getTarget();

// most portable way to look for the underlying provider.
// Note that at this point in the dependency we don't know the
// actual implementation-specific Session type
EntityManager myEntityManager = theEntityManager;
theActualSession = myEntityManager.getDelegate();
while (theActualSession instanceof EntityManager)
{
theActualSession = ((EntityManager) theActualSession).
getDelegate();
}
}
}
Hibernate should work OK regardless of the server that it's used with.
After all, Hibernate is certified JPA-compatible, and the ability to
extract implementation-specific stuff is just Java code after
all...nothing mysterious about it.

Nomenclature aside, calling getDelegate() on an EntityManager will (by
specification) also work with Toplink. After that the methods (for
obtaining sessions or units of work) do differ.
What I am trying to do is to be able to retrieve the implementation-specific
Session for any JPA-compatible implementation within any EJB Container
provider.

This is because I would like to offer the EJB Bean the full fledge DAO
functionality that uses implementation-specific extensions e.g. Hibernate's
Criteria API or TopLink's whatever similar Criteria API they have.

For my examples I used Apache's OpenEJB implementation. When the
EntityManager gets injected in my Bean it looks like:

org.apache.openejb.persistence.JtaEntityManager whose getDelegate returns a
org.hibernate.ejb.EntityManagerImpl whose getDelegate returns a
org.hibernate.Session

Regards,
Giovanni
 

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top