Announcement Announcement Module
Collapse
No announcement yet.
Spring + JBoss + JPA + Hibernate + JTA -> no success... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring + JBoss + JPA + Hibernate + JTA -> no success...

    Hello,

    Maybe this is a repost, but after some hours of searching, I did not found a working solution, nor config, nor applicable solution for my problem.

    Goal: To use a generic way to use JPA + hibernate (annotations) inside a JBoss application server, glued together with spring, and using where possible JTA and DataSource configurations from JBoss... Or at least some configuration that works !

    The problem ? : Until now, I found something that does deploy, but when a persistence create/update is called, nothing is saved to the database !! There is something wrong with the transactions I guess...

    First the stuff that I use:

    - JBoss 5.0.1 (with all hibernate & jpa libs under common)
    - Spring 2.5
    - JPA
    - Hibernate 3.2.5.ga (?)
    - MySQL 5.1.*
    - Java SE jdk 1.6.0

    I used as default out of the box Jboss deployment on a linux server.
    So, I also use the default server/default/ location.

    * Under the Jboss common/lib directory, I only added the mysql connector jar. I leave all the hibernate jars alone, because I can't get Jboss to start anymore. I also DO NOT include hibernate jars in my web application deployment war.

    * I defined in the JBoss access to a datasource: mysql-ds.xml
    under <jboss>/server/default/deploy :
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <datasources>
      <local-tx-datasource>
        <jndi-name>MySqlDS</jndi-name>
        <connection-url>jdbc:mysql://127.0.0.1:3306/testdb</connection-url>
        <driver-class>com.mysql.jdbc.Driver</driver-class>
        <user-name>felixthahousecat</user-name>
        <password>mylittlesecret</password>
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
        <connection-property name="autoReconnect">true</connection-property>
    
        <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
        <metadata>
           <type-mapping>mySQL</type-mapping>
        </metadata>
      </local-tx-datasource>
    </datasources>
    * Now, describing the "test" application I am writing: just a simple "ping" that writes a message in the database - to keep it simple.

    Stuff that I use:
    - entity class that maps to my database table (PingEntity)
    - GenericDAO and implementation to do generic CRUD operations
    - JPA Util to initialize my DAO's via spring wiring
    - persistence.xml , spring-config.xml

    * The Java Code : (the spring config is below)

    - The entity class:
    Code:
    // ...
    
    @javax.persistence.Entity
    @javax.persistence.Table(name="ping",schema="testdb")
    public class PingEntity implements SerializableBean<Long> {
    
        @javax.persistence.Id
        @javax.persistence.GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;
    
        @javax.persistence.Column(name="pingtext", length=300)
        private String pingText;
    
        public PingEntity(){  }
    
       // ... getters, setters, etc...
    - the DAO for the Ping Entity is very short:
    Code:
    public class PingDao extends GenericDAOImpl<PingEntity,Long> implements GenericDAO<PingEntity,Long>{
          // no extra behaviour that the default CRUD operations...
    }
    - the GenericDao(Impl) I wrote, is an implementation based on examples you find plenty on the internet.

    Code:
    public abstract class GenericDAOImpl<T extends SerializableBean<PK>, PK extends Serializable> implements GenericDAO<T, PK> {
    
        private Class<T> persistentClass;
        private EntityManager em;
    
        public GenericDAOImpl() {
              this.persistentClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
              this.em = JPAUtil.getEntityManager();
        }
     
        @Override
        public PK create(T newInstance) {
    	em.persist(newInstance);
        	return (PK) newInstance.getId();
        }
    
        @Override
        public T read(PK id) {
     	return em.find(persistentClass,id);
        }
        
        // and delete, update, seach via criteria, etc....
    The JPAUtil is just a helper to get to the entityManager. It will be initialized in the spring config.

    Code:
    public class JPAUtil {
    
        private EntityManagerFactory entityManagerFactory;
        private static JPAUtil _;
    
        JPAUtil(EntityManagerFactory emf){
               this.entityManagerFactory = emf;
               _ = this;
        }
    
        public static EntityManager getEntityManager() {
              if(_==null) getDefault();  // only used outside container as singleton !
              return _.entityManagerFactory.createEntityManager();
        }
        // ....
    - a service layer class between just delegates to correct dao, so this is the PingServiceManager, that willl be wired in place in the spring config:
    Code:
    public class PingServiceManager {
    
        private PingDao pingDao; 
    
        // setter for pingDao (for spring)
    
        public Long ping(String message){
            Long result = new Long(-1);
            if(pingDao!=null)
                result = pingDao.create(new PingEntity(message));
            return result;
        }
        // ....
    - via a simple servlet, I get the DAO for the ping entity, and try to create a save in the database

    Code:
    public class PingServlet extends HttpServlet {
       
         protected void processRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
               PingService foo = (PingService ) WebApplicationContextUtils.getWebApplicationContext(getServletContext()).getBean("pingService");
               Long id = foo.ping("Ping From Servlet");
               System.out.println("Done Testing - id = " + id);
        }
    // but here the id is always 0 !!! So it means that it is not saved in database.

    ===> CONTINUES IN NEXT POST

  • #2
    ===> Continues Here ===>


    * The configuration files :

    - persistence.xml (under my sources, META-INF directory)

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    
      <persistence-unit name="MyPU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:MySqlDS</jta-data-source>
        <properties>
          <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
    
          <property name="jboss.entity.manager.factory.jndi.name" value="java:/MyPU"/>
    
          <property name="hibernate.hbm2ddl.auto" value="update"/>
          <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
          <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
    
          <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/testdb"/>
          <property name="hibernate.connection.username" value="felixthahousecat" />
          <property name="hibernate.connection.password" value="mylittlesecret" />
    
          <property name="hibernate.transaction.flush_before_completion" value = "true"/>
          <property name="hibernate.cache.use_second_level_cache" value="false" />
          <property name="connection.autocommit" value="true" />
    
          <property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>
          <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
    
        </properties>
      </persistence-unit>
    </persistence>
    maybe there are too much properties set because of trying to get the stuff to work - feel free to reply what can be deleted !!!


    - now the spring configuration file : applicationContext.xml (under WEB-INF)

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:jee="http://www.springframework.org/schema/jee"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
    
    
        <jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/MyPU"/>
    
        <!-- Let's access the JTA transaction manager of the application server -->
        <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    
            <property name="autodetectTransactionManager" value="true"/>
            <property name="autodetectUserTransaction" value="true"/>
            <property name="transactionManagerName" value="java:/TransactionManager"/>
        </bean>
    
         <!--  MAPPING OF THE DAO's -->
    
        <bean id="jpaUtil" class="be.pedl.persistence.dao.util.JPAUtil" scope="singleton" >
            <constructor-arg ref="entityManagerFactory" />
            <property name="enableTransactions" value="false" />
        </bean>
    
        <!-- Import all DAO Beans -->
        <bean id="pingDao" class="be.pedl.db.dao.PingDao" />
    
        <!-- Service Layer -->
        <bean id="pingServiceManager" class="be.pedl.service.PingServiceManager">
            <property name="pingDao" ref="pingDao"/>
        </bean>
    
    
        <tx:advice id="managerTxAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="*" propagation="REQUIRED" />
            </tx:attributes>
        </tx:advice>
        <aop:config>
            <aop:pointcut id="managerMethods" 
                expression="execution(* be.pedl.service.PingServiceManager.* (..))" />
            <aop:advisor advice-ref="managerTxAdvice" pointcut-ref="managerMethods" />
        </aop:config>
    
    </beans>

    - finally some web.xml stuff:

    Code:
        // ...
        <context-param>
            <description>Spring configuration file</description>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext.xml</param-value>
        </context-param>
    
        <listener>
            <description>Spring Loader</description>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
         <persistence-unit-ref>
            <description> Persistence unit for the test application. </description>
            <persistence-unit-ref-name>persistence/MyPU</persistence-unit-ref-name>
            <persistence-unit-name>MyPU</persistence-unit-name>
        </persistence-unit-ref>
    
        // <servlet> and </servlet-mapping>

    * The WAR libs :

    What is inside my WEB-INF/lib folder:
    - asm-all-3.1.jar (otherwise i got class not found for aop)
    - spring_2.5.jar
    - aspectjrt.jar
    - aspectjweaver.jar



    I mainly based my workflow on this article:
    http://www.swview.org/node/214


    I hope anyone can help me. If clarification is needed, please ask me.

    Peter

    Comment


    • #3
      - the GenericDao(Impl) I wrote, is an implementation based on examples you find plenty on the internet.

      Code:
      public abstract class GenericDAOImpl<T extends SerializableBean<PK>, PK extends Serializable> implements GenericDAO<T, PK> {
      
          private Class<T> persistentClass;
          private EntityManager em;
      
          public GenericDAOImpl() {
                this.persistentClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                this.em = JPAUtil.getEntityManager();
          }
       
          @Override
          public PK create(T newInstance) {
      	em.persist(newInstance);
          	return (PK) newInstance.getId();
          }
      
          @Override
          public T read(PK id) {
       	return em.find(persistentClass,id);
          }
          
          // and delete, update, seach via criteria, etc....
      In your create-method you return the id of the instance you provide to the method. Your post is not complete yet, so don't shoot me if I'm wrong, but I had a similar case. In this perticular case the em.persist method returned the entity that is saved. This is a new Instance, not the one provided to the method. This new instance does have an Id.

      Comment


      • #4
        Originally posted by robinvp View Post
        In your create-method you return the id of the instance you provide to the method. Your post is not complete yet, so don't shoot me if I'm wrong, but I had a similar case. In this perticular case the em.persist method returned the entity that is saved. This is a new Instance, not the one provided to the method. This new instance does have an Id.
        The em.persist is a void method, because I use the javax.persistence and not the hibernate libraries. Normally, it should modify the new instance (i used it before on a non-container environment, and it worked like a charm). also works fine with Tomcat. Does not work with jboss...

        yes, my post was not complete, but for some reason i cannot complete it... it was too long ?

        Comment


        • #5
          Just a quick question, have you tried using JpaDaoSupport to extend your GenericDao from? Or does this not meet your requirements?

          Comment


          • #6
            ===> CONTINUED FROM PREVIOUS POST[/QUOTE]

            * The Configuration part is below :

            - The JPA requires to provide a persistence.xml where I use the JBOSS databasource that i declared on the server :
            (it is inside my src-path, under META-INF dir)

            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
              <persistence-unit name="MyPU" transaction-type="JTA">
                <provider>org.hibernate.ejb.HibernatePersistence</provider>
                <jta-data-source>java:MySQLDS</jta-data-source>
                <properties>
                  <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
                  <property name="jboss.entity.manager.factory.jndi.name" value="java:/MyPU"/>
                  <property name="hibernate.hbm2ddl.auto" value="update"/>
                  <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
                  <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/testdb"/>
                  <property name="hibernate.connection.username" value="felixdahousecat"/>
                  <property name="hibernate.connection.password" value="mylittlesecret"/>
                  <property name="hibernate.transaction.flush_before_completion" value="true"/>
                  <property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>
                  <property name="hibernate.cache.use_second_level_cache" value="false"/>
                  <property name="connection.autocommit" value="true"/>
                </properties>
              </persistence-unit>
            </persistence>
            Some of these properties probably can be removed. but I had some problems while deploying, and with this set it worked. feel free to comment which to delete.

            - I use spring wiring to get all the stuff together. This is my applicationContext.xml

            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <beans xmlns="http://www.springframework.org/schema/beans"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:aop="http://www.springframework.org/schema/aop"
                   xmlns:tx="http://www.springframework.org/schema/tx"
                   xmlns:jee="http://www.springframework.org/schema/jee"
                   xsi:schemaLocation="
                   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                   http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
            
                <!-- In a fully J5EE compatible environment, the following xml tag should work in accessing the EMF -->
                <jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/MyPU"/>
            
                <!-- Let's access the JTA transaction manager of the application server -->
                <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
                    <property name="autodetectTransactionManager" value="true"/>
                    <property name="autodetectUserTransaction" value="true"/>
                    <property name="transactionManagerName" value="java:/TransactionManager"/>
                    <property name="userTransactionName" value="UserTransaction"/>    </bean>
            
            
                 <!--  MAPPING OF THE DAO's -->
                <bean id="jpaUtil" class="org.maldiva.persistence.dao.util.JPAUtil" scope="singleton" >
                    <constructor-arg ref="entityManagerFactory" />
                </bean>
            
            
                <bean id="pingDao" class="be.pedl.test.db.dao.PingDao" />
            
                <bean id="pingServiceManager" class="be.pedl.test.service.PingServiceManager">
                    <property name="pingDao" ref="pingDao"/>
                </bean>
            
            
                <tx:advice id="managerTxAdvice" transaction-manager="transactionManager">
                    <tx:attributes>
                        <tx:method name="*" propagation="REQUIRED" />
                    </tx:attributes>
                </tx:advice>
            
                <aop:config>
                    <aop:pointcut id="managerMethods" 
                        expression="execution(* be.pedl.test.service.PingServiceManager.* (..))" />
                    <aop:advisor advice-ref="managerTxAdvice" pointcut-ref="managerMethods" />
                </aop:config>
            
            </beans>
            - and finally my web.xml :
            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
                <servlet>
                    <servlet-name>PingServlet</servlet-name>
                    <servlet-class>be.pedl.test.servlet.PingServlet</servlet-class>
                    <load-on-startup>1</load-on-startup>
                </servlet>
                <servlet-mapping>
                    <servlet-name>PingServlet</servlet-name>
                    <url-pattern>/ping</url-pattern>
                </servlet-mapping>
                <session-config>
                    <session-timeout>
                        30
                    </session-timeout>
                </session-config>
                <welcome-file-list>
                    <welcome-file>index.jsp</welcome-file>
                </welcome-file-list>
            
                <context-param>
                    <description>Spring configuration file</description>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>/WEB-INF/applicationContext.xml</param-value>
                </context-param>
            
                <listener>
                    <description>Spring Loader</description>
                    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
                </listener>
            
                <persistence-unit-ref>
                    <description> Persistence unit for Test. </description>
                    <persistence-unit-ref-name>persistence/MyPU</persistence-unit-ref-name>
                    <persistence-unit-name>MyPU</persistence-unit-name>
                </persistence-unit-ref>
            
            </web-app>

            The web application is packaged in a WAR, with
            - compiled code under: WEB-INF/classes
            - libs under : WEB-INF/lib
            - spring-2.5.jar
            - commons-logging-1.1.jar
            - cglib-2.2.jar
            - aspectjweaver.jar
            - aspectjrt.jar
            - asm-all-3.1.jar
            - Config files all under WEB-INF:
            - applicationContext.xml
            - jboss-web.xml
            - web.xml


            In the logging of Jboss it seems that all starts up, finds the table mapping, registers all spring stuff... everything is ready...
            but as soon as I create/save/update/delete.... it does not commit it in database... it's just "lost".

            Nothing happens in database.

            If more info is needed, I will gladly supply it !!
            Please give me some good pointers.

            As I discussed with someone else, I do not use Transaction annotations... I do not see where/if it helps... Advice is also appriciated.


            Peter

            Comment


            • #7
              Originally posted by robinvp View Post
              Just a quick question, have you tried using JpaDaoSupport to extend your GenericDao from? Or does this not meet your requirements?
              No I haven't used it. You probably are suggesting the Dao templating of spring ?
              Well, the initial goal is not to insert any spring dependencies or hibernate dependencies into my GenericDao's module. It purely uses javax.persistency. But maybe it is missing some JTA-stuff then ?...
              If needed, I can fully post the full blown implementation of this generic implementation. It worked find stand alone, under tomcat. but not in a jboss container

              Comment


              • #8
                JpaDaoSupport/JpaTemplate isn't recommended, use a plain jpa api dao/repository.

                The problem here is that you are trying to use a spring transactional entitymanager in a jboss environment. JBoss is very picky and very restrictive in what it allows (and trying to work around it is to hard, me and JBoss aren't best of friends ). Next to that you are creating an entitymanager yourself outside the scope of spring (by your JPAUtil class which I would suggest you abandon as quickly as possibly!) and hence spring cannot nor will applu transactions.

                Comment


                • #9
                  For the record, I based my findings on the very clear article
                  http://www.swview.org/node/214

                  this was my starting point...

                  Comment


                  • #10
                    Originally posted by Marten Deinum View Post
                    JpaDaoSupport/JpaTemplate isn't recommended, use a plain jpa api dao/repository.

                    The problem here is that you are trying to use a spring transactional entitymanager in a jboss environment. JBoss is very picky and very restrictive in what it allows (and trying to work around it is to hard, me and JBoss aren't best of friends ). Next to that you are creating an entitymanager yourself outside the scope of spring (by your JPAUtil class which I would suggest you abandon as quickly as possibly!) and hence spring cannot nor will applu transactions.
                    Hello Marten,

                    Oke, I agree, I do not like Jboss either... But it is something I am stuck with... so I have to find a solution.

                    Oke, so you suggest abandoning the JPA Util... please suggest another way to do it.
                    Injecting the entityManagerFactory in each DAO separately ?

                    Comment


                    • #11
                      I suggest you read the reference guide let spring inject the EntityManger (not the EntityManagerFactory) that way you should get a transactional EntityManager. Simple create a field and annotate it with @PersistenceContext and configure the appropriate postprocessor for it. It is all explained in the reference guide.

                      You should use dependency injection where possible, if you need to resort to static lookup methods I always try to reconsider.

                      Comment


                      • #12
                        Just to give some feedback... I found a way that works... but probably is horribly wrong ...

                        Against the advise not to inject the entity manager factory, I now inject it in the DAO. ( So I don't use any JPAUtil anymore that will give an entity manager to my DAO's via static methods).

                        Instead, I use the injected entity manager factory in the abstract GenericDaoImpl to get an EntityManager.

                        code example:

                        * GenericDaoImpl
                        Code:
                           public abstract class GenericDAOImpl<T extends SerializableBean<PK>, PK extends Serializable> implements GenericDAO<T, PK> {
                        
                        
                                   private Class<T> persistentClass;
                                   private EntityManagerFactory emf;
                        
                                   // setter for emf
                                   public void setEntityManager(EntityManagerFactory emf){ this.emf = emf; }
                         
                                  // ...
                        
                                 private EntityManager getEntityManager(){
                                         return emf.createEntityManager();
                                 }
                         
                                 // ...
                         
                                  @Override
                                  public PK create(T newInstance) {
                        	    getEntityManager().persist(newInstance);
                        	    return (PK) newInstance.getId();
                                  }
                               
                                 // the same for delete and update ...
                        (this is as I noticed exactly the same now as in an article I reported earlier...)


                        * My spring config applicationContext.xml now is:

                        Code:
                        <?xml version="1.0" encoding="UTF-8"?>
                        <beans xmlns="http://www.springframework.org/schema/beans"
                               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                               xmlns:aop="http://www.springframework.org/schema/aop"
                               xmlns:tx="http://www.springframework.org/schema/tx"
                               xmlns:jee="http://www.springframework.org/schema/jee"
                               xsi:schemaLocation="
                               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                               http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
                        
                            <jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/MyPU"/>
                        
                            <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
                                <property name="transactionManagerName" value="java:/TransactionManager"/>
                                <property name="userTransactionName" value="UserTransaction"/>
                            </bean>
                        
                            <bean id="pingDao" class="be.pedl.test.db.dao.PingDao">
                                <property name="entityManagerFactory" ref="entityManagerFactory"/>
                            </bean>
                        
                            <bean id="pingService" class="be.pedl.test.service.PingServiceManager">
                                <property name="pingDao" ref="pingDao"/>
                            </bean>
                        
                            <tx:advice id="managerTxAdvice" transaction-manager="transactionManager">
                                <tx:attributes>
                                    <tx:method name="get*" read-only="true"/>
                                    <tx:method name="*" />
                                </tx:attributes>
                            </tx:advice>
                        
                            <aop:config>
                                <aop:pointcut id="managerMethods" 
                                    expression="execution(* be.pedl.test.service.PingService.* (..))" />
                                <aop:advisor advice-ref="managerTxAdvice" pointcut-ref="managerMethods" />
                            </aop:config>
                        
                        </beans>
                        So, still depending on aop to add transactions on my methods..


                        * My persistence.xml is also very simple :

                        Code:
                        <?xml version="1.0" encoding="UTF-8"?>
                        <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
                          <persistence-unit name="MyPU" transaction-type="JTA">
                            <provider>org.hibernate.ejb.HibernatePersistence</provider>
                            <jta-data-source>java:MySQLDS</jta-data-source>
                            <properties>
                              <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
                              <property name="jboss.entity.manager.factory.jndi.name" value="java:/MyPU"/>
                            </properties>
                          </persistence-unit>
                        </persistence>

                        * The "service" class is PingServiceManager, not annotating transaction at al...

                        Code:
                        public class PingServiceManager implements PingService {
                            private PingDao pingDao;   // injected by spring
                        
                            // ...
                        
                            @Override
                            public Long ping(String message){
                                return pingDao.create(new PingEntity(message));
                            }
                        Which now returns the exact correct ID of the entity created in database !!
                        And also, the entries are written and collected by finder methods correctly.


                        However... I have my doubts... because,
                        * I create an entityManager everytime I do a persistence action in the DAO... This could not be meant to be like that, right ??
                        * I set the entitymanagerfactory in the dao's
                        * I don't see any evidence that transactions are applied by the container (how do I see that happening ?)
                        * no extra annotations used...

                        Comments or remarks are welcome.
                        Also pointers to howto's that show the REAL solution are very welcome... not just "you are wrong, just read the manual" -like answers please ! (at least give me the link to the correct guides )

                        Comment


                        • #13
                          maybe this helps

                          you could try to extend the JpaDAOSupport class for your DAOImpl, it takes an entityManager factory as property
                          Code:
                          getJpaTemplate.persist(entity) or any other method inside your DAO

                          Comment


                          • #14
                            Which isn't the recommended way doing JPA with spring, just as using HibernateDaoSupport/HibernateTemplate isn't recommended anymore. It is just there for consistency.

                            Comment

                            Working...
                            X