Announcement Announcement Module
Collapse
No announcement yet.
EntityManager not persisting to database Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • EntityManager not persisting to database

    I'm not receiving any errors or exceptions but the data I'm persisting is not being stored in the database. I'm using Spring with JPA and annotations on Tomcat. Am I missing something?

    db.xml
    Code:
       <tx:annotation-driven transaction-manager="dbTransactionManager" mode="aspectj" />
       <context:property-placeholder location="classpath:/properties/database.properties"/>
       <context:component-scan base-package="net.fractech.fds.dao" />
       <bean id="entityManagerFactory"
             class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
          <property name="persistenceUnitName" value="persistenceUnit"/>
          <property name="dataSource" ref="dbDataSource"/>
       </bean>
       <bean id="dbTransactionManager"
             class="org.springframework.orm.jpa.JpaTransactionManager">
          <property name="entityManagerFactory" ref="entityManagerFactory"/>
       </bean>
       <bean id="dbDataSource"
             class="com.mchange.v2.c3p0.ComboPooledDataSource"
             destroy-method="close">
          <property name="driverClass" value="${jdbc.driverClassName}" />
          <property name="jdbcUrl" value="${jdbc.url}" />
          <property name="user" value="${jdbc.username}" />
          <property name="password" value="${jdbc.password}" />
       </bean>
       <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
          <property name="dataSource" ref="dbDataSource" />
          <property name="packagesToScan"
                    value="net.fractech.ops.fds.db" />
          <property name="hibernateProperties">
             <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.id.new_generator_mappings">true</prop>
                <prop key="javax.persistence.validation.mode">NONE</prop>
             </props>
          </property>
       </bean>
       <bean id="majorStageDAO"
             class="net.fractech.ops.fds.db.JPAMajorStageDAO" />
    persistence.xml
    Code:
       <persistence-unit name="persistenceUnit"
                         transaction-type="RESOURCE_LOCAL">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <mapping-file>WEB-INF/config/spring/db.xml</mapping-file>
          <properties>
             <property name="hibernate.dialect"
                       value="org.hibernate.dialect.SQLServerDialect" />
             <property name="hibernate.hbm2ddl.auto"
                       value="validate" />
             <property name="hibernate.ejb.naming_strategy"
                       value="org.hibernate.cfg.DefaultNamingStrategy" />
             <property name="hibernate.connection.charSet"
                       value="UTF-8" />
          </properties>
       </persistence-unit>
    application.xml
    Code:
       <context:annotation-config />
       <context:spring-configured />
       <import resource="config/spring/db.xml"/>
    JPAMajorStageDAO.java
    Code:
    @Repository
    public class JPAMajorStageDAO{
       @PersistenceContext
       private EntityManager entityManager;
    
       @Transactional(rollbackFor=Throwable.class)
       public void createMajorStage()  {
             ...
    
             well = new WellEntity(1, "Well Name", "Well Location");
    
             this.entityManager.persist(well);
    
             ....
       }
    }

  • #2
    Hello

    1) Could you post your POJO that represent the Entity?
    2) how you are injecting the EntityManager to your DAO class?
    3) Your DAO class must implement an interface since Spring when work with Transactions use the Proxy Pattern
    4) Perhaps

    Code:
                <prop key="javax.persistence.validation.mode">NONE</prop>
    are hidding some errors?

    5)

    Code:
     @Transactional(rollbackFor=Throwable.class)
       public void createMajorStage()  {
             ...
    
             well = new WellEntity(1, "Well Name", "Well Location");
    
             this.entityManager.persist(well);
    
             ....
       }
    Be sure in the red part your code is not making a rollback

    Comment


    • #3
      Here is the POJO entity

      Code:
      @Entity
      @Table(name="Well")
      public class WellEntity implements Serializable
      {
         private String location;
         private String name;
         private int customerIdFK;
         private int id;
      
         public WellEntity()   {   }
      
         public WellEntity(final int customerIdFK_, final String name_, final String location_)  {
            this.customerIdFK = customerIdFK_;
            this.name = name_;
            this.location = location_;   }
      
         @NotNull
         @Column(name="Customer_ID_FK")
        public int getCustomerIdFK()   {      return(this.customerIdFK);   }
      
         public void setCustomerIdFK(final int customerIdFK_)   {      this.customerIdFK = customerIdFK_;   }
      
         @Id
         @GeneratedValue(strategy=GenerationType.AUTO)
         @NotNull
         @Column(name="FDS_Well_ID")
         public int getId()   {      return(this.id);   }
      
         public void setId(final int id_)   {      this.id = id_;   }
      
         @NotNull
         @Column(name="Well_Location",
                 length=50)
         public String getLocation()   {      return(this.location);   }
      
         public void setLocation(final String location_)   {      this.location = location_;   }
      
         @NotNull
         @Column(name="Well_Name",
                 length=50)
         public String getName()   {      return(this.name);   }
      
         public void setName(final String name_)   {      this.name = name_;   }
      }
      2) The entityManager injection is defined by previously posted code. Specifically
      Code:
      @Repository
      public class JPAMajorStageDAO{
         @PersistenceContext
         private EntityManager entityManager;
      int the JPAMajorStageDAO.java object.

      3) I'm not using an interface at this point. I do plan to move that direction but I don't believe that would cause my problem since I believe the spec states the @Transactional is required on the concrete class not the interface anyway.
      4) I'll try removing the NONE.
      5) There is no rollback code.

      Comment


      • #4
        Hello

        Just some final observations

        1) why the follow

        Code:
        @NotNull
        @Column(name="Customer_ID_FK")
        public int getCustomerIdFK()   {      
             return(this.customerIdFK);   
        }
        
        public void setCustomerIdFK(final int customerIdFK_)   {      
             this.customerIdFK = customerIdFK_;   
        }
        
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @NotNull
        @Column(name="FDS_Well_ID")
        public int getId()   {      
              return(this.id);   
        }
        
        public void setId(final int id_)   {  
            this.id = id_;   
        }
        First time I see *final* in the setter method in a POJO/Entity class

        2) Could you post the generated table generated from this Entity class?, I am worry about your customerIdFK declaration, since it is a FK it should be a Custom class type referencing other Custom Class not a int

        3) how you are filling the data your WellEntity class just before to proceed to call the DAO method to save/persist it? (doubt related about the point 2)

        3) I'm not using an interface at this point. I do plan to move that direction but I don't believe that would cause my problem since I believe the spec states the @Transactional is required on the concrete class not the interface anyway.
        You should use it, since when Spring work with Transactions it use the Proxy Pattern to work with AOP to apply the Transactions

        The final observation is, when you just only startup the tomcat container, did you check the log files

        Comment


        • #5
          Thanks for the assistance.

          1) Concerning the final, I checked the box for eclipse to auto include final in certain situations and thus eclipse performs that operation.
          2) I'm hadn't gotten to changing the int to the custom class reference yet, but I will get to that now and see if that is the issue.
          3) Concerning the interface, that doesn't apply to the domain model (i.e. @Entity classes) or service layer, but just the DAO layer, correct?

          Everything looks good in the logs.

          I'm creating a scaled down project to test with. I'll start with a single entity in the db without any foreign keys to see if that works and then build from there to see if the above mentioned items are the issue or not. I will post my results.

          Comment


          • #6
            Hello

            Thanks for the assistance.
            You're welcome

            1) Concerning the final, I checked the box for eclipse to auto include final in certain situations and thus eclipse performs that operation.
            OK, normally I never have seen before

            2) I'm hadn't gotten to changing the int to the custom class reference yet, but I will get to that now and see if that is the issue.
            I think you should do this right now, I never have seen before this approach, and I remember a lot of problems in other post when this approach is used, ORM makes relations between/among classes

            3) Concerning the interface, that doesn't apply to the domain model (i.e. @Entity classes) or service layer, but just the DAO layer, correct?
            Yes and No, interfaces must be used for DAO and Service layer, has no sense for a Controller, same appreciation for Entities, it represent a noun

            I'll start with a single entity in the db without any foreign keys to see if that works and then build from there to see if the above mentioned items are the issue or not
            Excellent and has sense, I used to work in such way, step by step

            Best Regards!

            Comment


            • #7
              I'm still having the problem with a very basic layout. Below are all files, nothing has been left out. I don't see any errors/exceptions but the information isn't showing up in the database.

              CustomerEntity.java
              Code:
              package net.fractech.ops.fds.db;
              
              import java.io.Serializable;
              
              import javax.persistence.Column;
              import javax.persistence.Entity;
              import javax.persistence.GeneratedValue;
              import javax.persistence.GenerationType;
              import javax.persistence.Id;
              import javax.persistence.Table;
              import javax.validation.constraints.NotNull;
              
              @Entity
              @Table(name="Customer")
              public class CustomerEntity implements Serializable{
                 private static final long serialVersionUID = -1306397204963780512L;
              
                 private String name;
                 private int id;
              
                 @Id
                 @GeneratedValue(strategy=GenerationType.AUTO)
                 @NotNull
                 @Column(name="FDS_Customer_ID")
                 public int getId()   {      return(this.id);   }
                 public void setId(final int id_)   {      this.id = id_;   }
              
                 @NotNull
                 @Column(name="Name",
                         length=50)
                 public String getName()   {      return(this.name);   }
                 public void setName(final String name_)   {      this.name = name_;   }
              }
              TestService.java
              Code:
              package net.fractech.ops.fds.db;
              
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.stereotype.Component;
              
              @Component
              public class TestService implements Runnable{
                 @Autowired(required=true)
                 private ITestDAO testDAO;
              
                 public TestService()   {
                    System.out.println("Started Test Service");
                    new Thread(this).start();
                 }
              
                 @Override
                 public void run()   {
                    try      {
                       Thread.sleep(1000);
                    }
                    catch(final Exception e)      {}
              
                    if(this.testDAO != null)      {
                       this.testDAO.performTest();
                    }
                    else      {
                       System.out.println("TestDAO is null");
                    }
                 }
              }
              ITestDAO.java
              Code:
              package net.fractech.ops.fds.db;
              
              public interface ITestDAO
              {
                 public void performTest();
              }
              TestDAO.java
              Code:
              package net.fractech.ops.fds.db;
              
              import javax.persistence.EntityManager;
              import javax.persistence.PersistenceContext;
              
              import org.apache.log4j.Logger;
              import org.springframework.stereotype.Repository;
              import org.springframework.transaction.annotation.Transactional;
              
              @Repository
              public class TestDAO implements ITestDAO {
                 private static Logger logger = Logger.getLogger(TestDAO.class);
              
                 @PersistenceContext
                 private EntityManager entityManager;
              
                 @Override
                 @Transactional(rollbackFor=Throwable.class)
                 public void performTest()   {
                    System.out.println("Performing test, em=" + this.entityManager);
                    final CustomerEntity customer = new CustomerEntity();
                    customer.setName("Test Customer");
                    this.entityManager.persist(customer);
                 }
              }
              web.xml
              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xmlns="http://java.sun.com/xml/ns/javaee"
                       xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
                       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
                       id="WebApp_ID"
                       version="3.0">
                 <listener>
                    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
                 </listener>
              </web-app>
              applicationContext.xml
              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <beans xmlns="http://www.springframework.org/schema/beans"
                     xmlns:context="http://www.springframework.org/schema/context"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://www.springframework.org/schema/beans
                                         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                         http://www.springframework.org/schema/context
                                         http://www.springframework.org/schema/context/spring-context-3.1.xsd" >    
                 <context:annotation-config />
                 <context:component-scan base-package="net.fractech.ops.fds.db" />
                 <context:spring-configured />
                 
                 <import resource="config/spring/db.xml"/>
              </beans>
              db.xml
              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <beans xmlns="http://www.springframework.org/schema/beans"
                     xmlns:context="http://www.springframework.org/schema/context"
                     xmlns:tx="http://www.springframework.org/schema/tx"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://www.springframework.org/schema/beans
                                         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                         http://www.springframework.org/schema/context
                                         http://www.springframework.org/schema/context/spring-context-3.1.xsd
                                         http://www.springframework.org/schema/tx
                                         http://www.springframework.org/schema/tx/spring-tx-3.1.xsd" >
              
                 <tx:annotation-driven transaction-manager="dbTransactionManager" mode="aspectj" />
                 <context:property-placeholder location="classpath:/properties/database.properties"/>
                 <context:component-scan base-package="net.fractech.fds.dao" />
              
                 <bean id="entityManagerFactory"
                       class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                    <property name="persistenceUnitName" value="persistenceUnit"/>
                    <property name="dataSource" ref="dbDataSource"/>
                 </bean>
                 
                 <bean id="dbTransactionManager"
                       class="org.springframework.orm.jpa.JpaTransactionManager">
                    <property name="entityManagerFactory" ref="entityManagerFactory"/>
                 </bean>
                    
                 <bean id="dbDataSource"
                       class="com.mchange.v2.c3p0.ComboPooledDataSource"
                       destroy-method="close">
                    <property name="driverClass" value="${jdbc.driverClassName}" />
                    <property name="jdbcUrl" value="${jdbc.url}" />
                    <property name="user" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                 </bean>
                 
                 <bean id="testDAO"
                       class="net.fractech.ops.fds.db.TestDAO" />
                 <bean id="testService"
                       class="net.fractech.ops.fds.db.TestService" />
              </beans>
              persistence.xml
              Code:
              <?xml version="1.0" encoding="UTF-8" standalone="no"?>
              <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           version="2.0"
                           xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
                 <persistence-unit name="persistenceUnit"
                                   transaction-type="RESOURCE_LOCAL">
                    <provider>org.hibernate.ejb.HibernatePersistence</provider>
                    <mapping-file>WEB-INF/config/spring/db.xml</mapping-file>
                    <properties>
                       <property name="hibernate.dialect"
                                 value="org.hibernate.dialect.SQLServerDialect" />
                                 
                       <property name="hibernate.hbm2ddl.auto"
                                 value="validate" />
                       <property name="hibernate.ejb.naming_strategy"
                                 value="org.hibernate.cfg.DefaultNamingStrategy" />
                       <property name="hibernate.connection.charSet"
                                 value="UTF-8" />
                    </properties>
                 </persistence-unit>
              </persistence>

              Comment


              • #8
                I added

                Code:
                entityManager.flush();
                after the persist call and got the following exception.

                Code:
                Exception in thread "Thread-15" javax.persistence.TransactionRequiredException: no transaction is in progress
                	at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:792)
                	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                	at java.lang.reflect.Method.invoke(Method.java:597)
                	at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
                	at $Proxy31.flush(Unknown Source)
                	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                	at java.lang.reflect.Method.invoke(Method.java:597)
                	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
                	at $Proxy30.flush(Unknown Source)
                	at net.fractech.ops.fds.db.TestDAO.performTest(TestDAO.java:31)
                	at net.fractech.ops.fds.db.TestService.run(TestService.java:24)
                	at java.lang.Thread.run(Thread.java:662)
                it seems I'm not creating the transaction. It has the @Transactional annotation and
                Code:
                   <tx:annotation-driven transaction-manager="dbTransactionManager" mode="aspectj" />
                and it's not being called within the same class so what am I doing wrong or missing?

                Comment


                • #9
                  It seems the problem was that I was using aspectj but didn't properly set it up. I couldn't get the aspectj to work but when I removed the mode="aspectj" from the annotation-driven attribute I was able to get the transactions working properly.

                  Code:
                  <tx:annotation-driven transaction-manager="dbTransactionManager" mode="aspectj" />

                  Comment

                  Working...
                  X