1 2 3 4 Previous Next 59 Replies Latest reply on Oct 15, 2012 6:43 AM by chrisharris

    How do I get a JPA EntityManager reference in Weld?

    sboscarine

      What do I need to do to get @PersistenceContext working in Weld? 


      I can confirm that JPA is configured correctly because I can access it via Persistence.createEntityManagerFactory(myunit).createEntityManager().  I included the sample below.  getTest() works, but create() fails because em is never injected. 


      What did I forget?



      import javax.enterprise.context.RequestScoped;
      import javax.inject.*;
      import javax.persistence.*;
      
      @RequestScoped  @Named
      public class BeanService {
              @Inject Bean bean;
      
              public String getTest(){
                      return Persistence.createEntityManagerFactory("myunit").createEntityManager().toString();
              }
      
              public void create(){
                      if(em == null){
                              throw new RuntimeException("em is null!");
                      }
                      em.persist(bean);
              }
      
              @PersistenceContext
              EntityManager em;
      }



        • 1. Re: How do I get a JPA EntityManager reference in Weld?
          asookazian

          Isn't there a working example of this the Weld distro?  hmmm....


          I found only one reference in the examples directory for PersistenceContext:


          @SessionScoped @Named
          public class Login implements Serializable {
          
              @Inject Credentials credentials;
              //@PersistenceContext EntityManager userDatabase;
          ...
          }



          Note that they are injecting the Credentials managed bean instance rather than the EntityManager interface.


          Only one reference to EntityManager in the examples directory as well.


          Pretty lame, sorry guys.


          So there is no example with JPA 2.0 persistence?  is that b/c the persistence provider for JPA 2.0 (Hibernate) is not ready??


          anyways, I'm hoping it's just a config issue for you, Steve...


          what is the equivalent of the components.xml in Weld app (I'm guessing beans.xml)?? and what does your persistence.xml look like?


          Interestingly, this link works: http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd


          this link is not available: http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd

          • 2. Re: How do I get a JPA EntityManager reference in Weld?
            paulmooney

            I don't have an answer yet either but this may help, though I don't exactly see why what you're doing won't work.

            • 3. Re: How do I get a JPA EntityManager reference in Weld?
              gavin.king

              What application server is this? Are you sure you have configured the container-managed EM?

              • 4. Re: How do I get a JPA EntityManager reference in Weld?
                asookazian

                compare:
                @Inject @CustomerDatabase EntityManager;


                versus:
                @PersistenceContext(unitName="CustomerDatabase") EntityManager;


                Is one wrong or right?  First one is type-safe but I'm wondering if the 2nd way is supported or not? 

                • 5. Re: How do I get a JPA EntityManager reference in Weld?
                  gavin.king

                  Yet another question that is covered in the documentation

                  • 6. Re: How do I get a JPA EntityManager reference in Weld?
                    gavin.king

                    (I mean Arbi's question.)

                    • 7. Re: How do I get a JPA EntityManager reference in Weld?
                      asookazian

                      I know, I know.  read the spec...



                      All managed beans may take advantage of Java EE component environment injection using @Resource, @EJB, @PersistenceContext, @PeristenceUnit and @WebServiceRef.
                      • 8. Re: How do I get a JPA EntityManager reference in Weld?
                        sboscarine

                        Gavin King wrote on Nov 18, 2009 18:27:


                        What application server is this? Are you sure you have configured the container-managed EM?


                        I'm using Jetty and Tomcat. 


                        How do I configure a container-managed EntityManager in Jetty and Tomcat? 


                        I have only used Hibernate 2+ with Spring (hence the earlier post asking for examples of configuration).



                        I added a persistence.xml to src/main/resources/META-INF/:


                        <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             version="1.0">
                             <persistence-unit name="myunit" transaction-type="RESOURCE_LOCAL">
                             <provider>org.hibernate.ejb.HibernatePersistence</provider>
                                  <properties>
                                       <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
                                       <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
                                       <property name="hibernate.connection.username" value="sa" />
                                       <property name="hibernate.connection.password" value="" />
                                       <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:todo" />
                                       <property name="hibernate.hbm2ddl.auto" value="create" />
                                  </properties>
                             </persistence-unit>
                        </persistence>



                        and added a few dependencies to my POM:


                                  <dependency>
                                       <groupId>javax.persistence</groupId>
                                       <artifactId>persistence-api</artifactId>
                                       <!-- 1.0, version derived from JBoss Bill of Materials) -->
                                  </dependency>
                                  <dependency>
                                       <groupId>org.hibernate</groupId>
                                       <artifactId>hibernate</artifactId>
                                       <version>3.2.6.ga</version>
                                       <exclusions>
                                            <exclusion>
                                                 <groupId>javax.transaction</groupId>
                                                 <artifactId>jta</artifactId>
                                            </exclusion>
                                       </exclusions>
                                  </dependency>
                                  <dependency>
                                       <groupId>org.hibernate</groupId>
                                       <artifactId>hibernate-entitymanager</artifactId>
                                       <version>3.4.0.GA</version>
                                  </dependency>
                                  <dependency>
                                       <groupId>org.hsqldb</groupId>
                                       <artifactId>hsqldb</artifactId>
                                       <version>1.8.0.10</version>
                                  </dependency>



                        The snippet above was added to the the archetype-generated POM.  Here's the latest archetype instructions:  http://www.seamframework.org/Documentation/WeldQuickstartForMavenUsers

                        • 9. Re: How do I get a JPA EntityManager reference in Weld?
                          gavin.king

                          There are no container managed entity managers in a servlet engine. That's a Java EE thing.


                          The CDI spec says:



                          All containers must support managed beans, producer methods and producer fields. Java EE and embeddable EJB contain- ers are required by the Java EE and EJB specifications to support EJB session beans and the Java EE component environ- ment. Other containers are not required to provide support for injection or lifecycle management of session beans or re- sources.

                          In your case, Weld is functioning is the other containers category.


                          So, one of the things that Seam3 needs to have, is a port of the seam-managed persistence contexts from Seam2. That's an easy job, but we have not done it yet. For now, I suppose you should just manage the EntityManager yourself, using the lifecycle defined by the JPA spec.

                          • 10. Re: How do I get a JPA EntityManager reference in Weld?
                            sboscarine

                            Gavin King wrote on Nov 18, 2009 20:02:


                            There are no container managed entity managers in a servlet engine. That's a Java EE thing.

                            The CDI spec says:

                            All containers must support managed beans, producer methods and producer fields. Java EE and embeddable EJB contain- ers are required by the Java EE and EJB specifications to support EJB session beans and the Java EE component environ- ment. Other containers are not required to provide support for injection or lifecycle management of session beans or re- sources.

                            In your case, Weld is functioning is the other containers category.


                            So how would a Tomcat user use JPA with CDI? 


                            I apologize, but I do not understand your response and I'm not sure why you're referring to the spec.  I am not stating that Weld is broken or violating the CDI specification.  I'm merely asking how I can write an application for Tomcat that uses CDI and JPA. 


                            I assumed that at some point, someone on the CDI/Weld team has written an application that uses JPA outside of a full JEE container.  If there are no Tomcat examples, are there SE examples somewhere?


                            • 11. Re: How do I get a JPA EntityManager reference in Weld?
                              gavin.king

                              So how would a Tomcat user use JPA with CDI?

                              Options:



                              1. call EntityManagerFactory.createEntityManager() directly to get the EM and EntityManager.close() to destroy it. Keep it in a @RequestScoped or @ConversationScoped bean.

                              2. Look at the code in Seam2 that does this, and port it to CDI (perhaps using a portable extension)

                              3. wait for Seam3 to release a portable extension that does persistence context management.


                              • 12. Re: How do I get a JPA EntityManager reference in Weld?
                                sboscarine

                                I assume that @Transactional won't work, either. 


                                So under what circumstances does Weld integrate with JPA out of the box? 


                                Does this mean we have to run JBoss 6 or Glassfish v3, both are in beta?


                                I think your response above will drastically hurt CDI's adoption rate.


                                I think the main use case of CDI is for applications that use JPA.  The majority of users are still on non-JEE compliant containers, especially Tomcat.  What precisely do you mean when you say We also have support for Servlet containers?  When you say you support a platform, I think it's generally implied that you have means for them to connect to a database out of the box. 

                                • 13. Re: How do I get a JPA EntityManager reference in Weld?
                                  gavin.king

                                  I assume that @Transactional won't work, either.

                                  At this time, you can assume that pretty much anything that is not defined by the CDI specification won't work. Weld, by design, is an implementation of CDI and not much more.


                                  We should not be throwing things like transaction and persistence context management into CDI/Weld because this is a core technology, like JPA/Hbernate, that does one thing well. It is meant to apply in lots of different environments, where, for example, there may be no databases, and no transactions. Other services should be layered on as modules.



                                  So under what circumstances does Weld integrate with JPA out of the box?

                                  In a Java EE 6 application server - where this integration is defined by the other Java EE specifications.



                                  Does this mean we have to run JBoss 6 or Glassfish v3, both are in beta? I think your response above will drastically hurt CDI's adoption rate. I think the main use case of CDI is for applications that use JPA. The majority of users are still on non-JEE compliant containers, especially Tomcat.

                                  If you want to use CDI with JPA in an environment (such as Tomcat or Jetty) which does not provide transaction and persistence context management, then you need an additional piece.


                                  That additional piece is Seam3. Seam3 will be a set of plugins for CDI (what we call portable extensions) that integrate with any CDI implementation (for example, Weld) and add additional functionality that is not defined by the CDI specification (for example, transaction and persistence context management).


                                  So there will be a seam-transaction.jar and a seam-persistence.jar that provide this functionality to your application, via CDI's portable SPIs. They will work with any CDI implementation (Weld, CanDI, Apache Open Web Beans, etc.


                                  We havn't implemented these things yet, because we were too busy getting Weld out the door in time for the EE 6 release.



                                  What precisely do you mean when you say "We also have support for Servlet containers"?

                                  We mean we support all the functionality defined by the CDI specification.



                                  When you say you support a platform, I think it's generally implied that you have means for them to connect to a database out of the box.

                                  The CDI spec has nothing to say about connecting to databases. You're mixing up CDI (a bean container) with Seam (an application platform).


                                  • 14. Re: How do I get a JPA EntityManager reference in Weld?
                                    asookazian

                                    Unfortunately and fortunately, CDI/Weld expose a lot of new concepts including interceptors, decorators, stereotypes, alternatives, and portable extensions.



                                    You're mixing up CDI (a bean container) with Seam (an application platform).

                                    This is going to be a big challenge for Seam developers: understanding that CDI is really only a subset of Seam and not intended for JPA support, etc.


                                    I feel Steve's pain...


                                    I'm very confused.  And at this point, unfortunately, it's possible that CDI/Weld may have a low adoption rate due to this kind of confusion and complexity in the API/concepts.  But we'll seem, it's still early...




                                    What precisely do you mean when you say We also have support for Servlet containers?


                                    We mean we support all the functionality defined by the CDI specification.


                                    Don't like that answer...

                                    1 2 3 4 Previous Next