users@glassfish.java.net

Re: OSGi Java EE hybrid example split into modules best practices

From: Sahoo <sanjeeb.sahoo_at_oracle.com>
Date: Sat, 25 Feb 2012 09:44:08 +0530

No, it is not impossible to inject an EM backed by an OSGi service working:
@Inject @OSGiService (...) EntityManager em;

You just need to write a producer CDI bean which produces EntityManager
and let the producer be injected with
@Inject @OSGiService EntityManagerFactory emf;

You could centralize the lifecycle management of EM in this producer
bean there by not having to do it repeatedly in many places. I will try
to come up with a sample when I have some time. I don't like the extra
XML code one has to write to get things working.

Thanks,
Sahoo


On Friday 24 February 2012 10:42 PM, Kirk Rasmussen wrote:
>
> I wrote this before I got your response in my JIRA ticket so this was
> simply a duplicate. I got all the fighterfish examples working and
> have a much better understanding then when I wrote this email.
>
> Is it impossible to inject EntityManager with CDI and OSGI bundle? I
> found an example using Blueprint Injection with Aries for both managed
> JPA and declarative transactions that was using EnitytManger that I
> referenced below from the upcoming Enterprise OSGi in Action book.
> That would help make the code less brittle IMHO (no need to
> programmatically create/close EnitytManger).
>
> Here was my follow up in the JIRA ticket that you may have missed:
>
> Thanks again for your help.
>
> http://java.net/jira/browse/GLASSFISH-18381
>
> One last thing that wasn't clear to me is about JPA bootstrapping. In
> the *ejbservice1* example you used managed JPA deployment which
> allowed you to simplify coding:
>
> @PersistenceContext
> private EntityManager em;
>
> whereas in *ejbservice2* you used unmanaged JPA and injected
> EntityManagerFactory
>
> @Inject
> @OSGiService(dynamic =true, serviceCriteria ="(persistence-unit=sample.uas.entities)")
> private EntityManagerFactory emf;
>
> so the code becomes more brittle (i.e. have to manually create/close
> EntityManager):
>
> EntityManager em = emf.createEntityManager();
> try {
> }finally {
> em.close();
> }
>
> I was wondering if this is the only option or is it possible to use
> managed JPA with CDI to inject EntityManager in the EJB similar to
> ejbservice1 example? Something like (doesn't work):
>
> @Inject
> @OSGiService(dynamic =true, serviceCriteria ="(persistence-unit=sample.uas.entities)")
> private EntityManager em;
>
> In the Enterprise OSGi in Action book they use managed JPA with
> declarative transactions exclusively in their examples (Apache Aries)
> using Blueprint, e.g.
>
> package fancyfoods.persistence;
>
> public class InventoryImpl implements Inventory {
>
> private EntityManager em;
>
> public void setEntityManager(EntityManager em) {
>
> this.em = em;
>
> }
>
> }
>
> <bean
>
> id="inventory"
>
> class="fancyfoods.persistence.InventoryImpl">
>
> <tx:transaction
>
> method="*"
>
> value="Required" />
>
> <jpa:context
>
> property="entityManager"
>
> unitname="fancyfoods" />
>
> </bean>
>
> So I'm hopeful this is possible to do with CDI as well.
>
> Thanks again
>
> References:
>
> http://aries.apache.org/modules/jpaproject.html^http://java.net/jira/images/icons/linkext7.gif
>
> http://www.manning.com/cummins/SourceCodeEnterpriseOSGiinAction.zip^http://java.net/jira/images/icons/linkext7.gif
>
>
> *From:*Sahoo [mailto:sanjeeb.sahoo_at_oracle.com]
> *Sent:* Friday, February 24, 2012 10:54 AM
> *To:* users_at_glassfish.java.net
> *Cc:* Kirk Rasmussen
> *Subject:* Re: OSGi Java EE hybrid example split into modules best
> practices
>
> I thought I answered this earlier, but apparently I have not. You need
> to inject EntityManagerFactory instead of EntityManager. Checkout
> https://svn.java.net/svn/glassfish~svn/trunk/fighterfish/sample/uas
> <https://svn.java.net/svn/glassfish%7Esvn/trunk/fighterfish/sample/uas>
> and look at
> ./ejbservice2/src/main/java/org/glassfish/fighterfish/sample/uas/ejbservice2/UserAuthServiceEJB2.java
>
> You can build them yourself and try out.
>
> I am traveling now, so expect some delays in replies.
>
> Thanks,
> Sahoo
> On Tuesday 21 February 2012 11:48 PM, Kirk Rasmussen wrote:
>
> Hello,
>
> I am very interested in the hybrid Java EE approach to OSGi that
> Glassfish supports to leverage declarative security and transaction
> propagation available in Java EE. I was able to get the EclipseCon
> demo app working fine.
>
> I was wondering if it is possible to split up the EJB and JPA
> portions. In other words I would like to have a persistence bundle
> that contains the entities with all the goodies (sharable, lazy
> loaded, 2^nd level cache) and a separate EJB service bundle.
>
> A more realistic service API would leverage Entities and not just Java
> primitives like Strings. For example, let's say the 'UserAuthService'
> added a new method:
>
> public interface UserAuthService {
>
> ...
>
> // EJB impl would have @RolesAllowed("admin") applied
>
> public User lookup(String name)
>
> }
>
> So now the common bundle would have a dependency on the Entity User.
> Seems logical to move this to another package / bundle, e.g.
> eclipsecon2011.osgieehol.persistence. From my understanding
> http://glassfish.java.net/public/GF-OSGi-Features.pdf the JPA bundle
> must include both the entities and the META-INF/persistence.xml file
> which I did.
>
> Now the EJB bundle only contains 'UserAuthServiceEJB' which I modified
> to lookup the EntityManager as an OSGi service (@PersistenceContext
> didn't work):
>
> @Stateless
>
> public class UserAuthServiceEJB implements UserAuthService
>
> {
>
> //_at_PersistenceContext
>
> @Inject @OSGiService(dynamic=true)
>
> private EntityManager em;
>
> ....
>
> }
>
> But it's not able to locate the JPA EntityManager
>
> [#|2012-02-21T12:06:21.679-0600|WARNING|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=26;_ThreadName=Thread-4;|EJB5184:A
> system exception occurred during an invocation on EJB
> UserAuthServiceEJB, method: public boolean
> eclipsecon2011.osgieehol.ejb_service.impl.UserAuthServiceEJB.login(java.lang.String,java.lang.String)|#]
>
> Caused by: java.lang.NullPointerException
>
> at
> eclipsecon2011.osgieehol.ejb_service.impl.UserAuthServiceEJB.login(UserAuthServiceEJB.java:27)
>
> What is the proper way to accomplish this?
>
> Thanks!
>
> "Do the right thing. It will gratify some people and astonish the
> rest." - Mark Twain
>