tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: Help with OpenEJB3 and Spring IoC
Date Fri, 06 Jun 2008 00:30:36 GMT
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&amp;useUnicode=true&amp;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.
>
>


Mime
View raw message