Hi Jon,
I wonder if it might be possible to pass the EntityManager through via
a custom Spring factory bean. Thinking you could create a stateless
bean with an @PersistenceContext ref in it, then use a factory bean to
look it up, pull the EntityManager out and return it.
Something like:
@Stateless
public class ResourceBean implements ResourceLocal {
@PersistenceContext(unitName="ApplicationEntityManager")
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
}
public interface ResourceLocal {
public EntityManager getEntityManager();
}
public class EntityManagerFactoryBean implements
org.springframework.beans.factory.FactoryBean {
public Object getObject() {
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
InitialContext context = new InitialContext(p);
ResourceLocal bean = (ResourceLocal)
context.lookup("ResourceBeanLocal");
return bean.getEntityManager();
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
public Class getObjectType(){
return EntityManager.class;
}
boolean isSingleton() {
return true;
}
}
You could likely expand the same bean and factory to handle anything
you wanted to pull from the environment, such as the DataSource,
though it sounds like you're really just after the EntityManager.
-David
On Jun 5, 2008, at 9:30 AM, Jon Carrera wrote:
I've been playing with OpenEJB for a few days now trying to make it
work with
an application that uses an EJB facade that delegates to a spring-
managed
service pojo that relies on an EAO to retrieve and persist data. So
far
OpenEJB works fine as a container for the ejb, but i can't still
figure out
how can I inject the PersistenceContext created by OpenEJB to the
EAO via
Spring IoC.
The EAO is a simple class that relies on the EntityManager to perform
persistence operations:
public class GenericEaoJpa<E, PK extends Serializable> implements
GenericEao<E, PK> {
protected final Log log = LogFactory.getLog(getClass());
private Class<E> persistentClass;
@PersistenceContext(unitName="ApplicationEntityManager")
private EntityManager em;
public GenericEaoJpa(Class <E> persistentClass) {
super();
this.persistentClass = persistentClass;
}
public boolean exists(Serializable id) {
E entity = em.find(persistentClass, id);
return entity == null? false:true;
}
public E get(PK id) {
E entity = em.find(persistentClass, id);
if (entity == null) {
log.warn("Uh oh, '" + this.persistentClass + "' object
with id
'" + id + "' not found...");
throw new
ObjectRetrievalFailureException(this.persistentClass,
id);
}
return entity;
}
public List<E> getAll() {
// TODO Auto-generated method stub
return em.createQuery("select " +
persistentClass.getName()).getResultList();
}
public void remove(PK id) {
E entity = get(id);
em.remove(entity);
}
public E save(E entity) {
em.persist(entity);
return entity;
}
}
I use the following code to initialize the openejb context in my
test case:
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
p.put("myDs", "new://Resource?type=DataSource");
p.put("myDs.JdbcDriver", "com.mysql.jdbc.Driver");
p.put("myDs.JdbcUrl",
"jdbc:mysql://localhost/midastest?
createDatabaseIfNotExist
=true&useUnicode=true&characterEncoding=utf-8");
p.put("myDs.UserName", "root");
p.put("myDs.Password", "");
this.context = new InitialContext(p);
ServiceFacadeBean service = (ServiceFacadeBean) context
.lookup("ServiceFacadeBeanLocal");
persistence.xml is defined as follows:
<persistence-unit name="ApplicationEntityManager"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>myDs</jta-data-source>
<class>model.MyEntity</class>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.apache.openejb.hibernate.TransactionManagerLookup"/>
</properties>
</persistence-unit>
Now, my problem is in the spring application context configuration
file. I
don't know if it is possible to obtain the EntityManager from the
openejb
jndi context or if there is an EntityManagerFactory in openejb that
i can
use to inject it to my EAO Pojo. An idea that ocurred to me is to use
spring's LocalContainerEntityManagerFactoryBean and pass the
dataSource from
the openejb jndi context
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:openejb/Resource/
myDs"/>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">
org.apache.openejb.client.LocalInitialContextFactory
</prop>
</props>
</property>
</bean>
<bean id="entityManagerFactory"
class
="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource">
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<!-- bean post-processor for JPA annotations -->
<bean
class
=
"org
.springframework
.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"
/>
<bean id="MyEntityEao"
class="eao.jpa.GenericEaoJpa">
<constructor-arg
value="model.MyEntity" />
</bean>
I get the following error when running the test
Invocation of init method failed; nested exception is javax.naming.N
ameNotFoundException: Name "java:openejb/Resource/myDs" not found.
Caused by: javax.naming.NameNotFoundException: Name
"java:openejb/Resource/myDs"
not found.
at
org.apache.openejb.core.ivm.naming.IvmContext.federate(IvmContext.jav
a:172)
at
org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:
129)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at
org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java
:123)
at
org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:85)
at
org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:121)
at
org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:146)
at
org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport
.java:93)
at
org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.j
ava:105)
at
org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(Jnd
iObjectFactoryBean.java:197)
at
org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(Jnd
iObjectFactoryBean.java:184)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:
1202)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.initializeBean(AbstractAutowireCapableBeanFactory.java:1172)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:428)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:251)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:156)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:248)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:160)
at
org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveReference(BeanDefinitionValueResolver.java:261)
at
org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveValueIfNecessary(BeanDefinitionValueResolver.java:109)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:
1100)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.populateBean(AbstractAutowireCapableBeanFactory.java:862)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:424)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:251)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:156)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:248)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:160)
I've been trying to retrieve the datasource from the jndi context with
different naming conventions with no success.
Maybe this is not the correct approach to solve the problem, so any
advice
would be very appreciated.
Thanks in advance.
--
View this message in context:
http://www.nabble.com/Help-with-OpenEJB3-and-Spring-IoC-tp17674222p17674222.html
Sent from the OpenEJB User mailing list archive at Nabble.com.