Results 1 to 7 of 7

Thread: No insert: Spring (3.x), Hibernate (3.5) and JPA (2.0)

  1. #1
    Join Date
    May 2010
    Posts
    1

    Default No insert: Spring (3.x), Hibernate (3.5) and JPA (2.0)

    No insert: Spring (3.x), Hibernate (3.5) and JPA (2.0)


    Hello everyone,

    I'm new to Spring and have one more question about the combination Spring (3.x), Hibernate (3.5) and JPA (2.0).
    My objective is to use a plain JPA DAO with Spring transaction management. My problem is that the createUser
    method does not cause a database insert.

    The DAO:

    Code:
    public class JpaPlainUserDAO implements UserDAO {
    
    	@PersistenceContext
    	private EntityManager entityManager;
      
      
    	public void setEntityManager(EntityManager entityManager) {
    		this.entityManager = entityManager;
    	}
    	
    	@Transactional(readOnly = false)
    	@Override
    	public void createUser(User user) {
    		entityManager.persist(user);
    	}
    
    	@Transactional(readOnly = true)
    	@Override
    	public User findByPrimaryKey(Long id) {
    		return entityManager.find(User.class, id);
    	}
    }

    The User class is an usual entity bean that has a OneToMany relationship to an entity bean Address and some simple
    fields.

    the spring beans config file:

    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:context="http://www.springframework.org/schema/context"
    	   xmlns:p="http://www.springframework.org/schema/p"
    	   xmlns:jee="http://www.springframework.org/schema/jee"
    	   xsi:schemaLocation="http://www.springframework.org/schema/beans
    	   			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    	   			http://www.springframework.org/schema/tx
    	   			http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    	   			http://www.springframework.org/schema/context
    				http://www.springframework.org/schema/context/spring-context-3.0.xsd
    				http://www.springframework.org/schema/jee
    				http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
    
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    	<property name="driverClass" value="org.postgresql.Driver"/>
    	<property name="jdbcUrl" value="jdbc:postgresql://localhost/testDB"/>
    	<property name="user" value="standard"/>
    	<property name="password" value="standard"/>
    	<!-- ... -->
        </bean>
    
        <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
    	
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="testUnit"/>
    	<property name="dataSource" ref="dataSource"/>
    
            <property name="jpaVendorAdapter">
               <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                  <property name="database" value="POSTGRESQL"/>
                  <property name="showSql" value="true"/>
                  <property name="generateDdl" value="true"/>
               </bean>
            </property>
    	<property name="jpaDialect" ref="jpaDialect"/>
        </bean>
    
        <tx:annotation-driven transaction-manager="transactionManager"/>
    
        <!-- also tried: org.springframework.orm.hibernate3.HibernateTransactionManager -->
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    	<property name="entityManagerFactory" ref="entityManagerFactory"/>
    	<property name="dataSource" ref="dataSource"/>
    	<property name="jpaDialect" ref="jpaDialect"/>
        </bean>
    
    
        <bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
          <property name="entityManagerFactory" ref="entityManagerFactory"/>
        </bean>
    	
        <bean id="jpaPlainUserDAO" class="com.test.dao.JpaPlainUserDAO">
    	<property name="entityManager" ref="entityManager"/>
        </bean>
    	
    	
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    
    </beans>

    the persistence.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence 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_2_0.xsd"
                 version="2.0">
    			 
    	 <persistence-unit name="testUnit" transaction-type="RESOURCE_LOCAL">
    		<provider>org.hibernate.ejb.HibernatePersistence</provider>
    		
    		<class>com.test.entity.User</class>
    		<class>com.test.entity.Address</class>
    		<exclude-unlisted-classes/>
    
    		<properties>
    			<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
    			<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    			<property name="hibernate.show_sql" value="true"/>				
    
    			<property name="hibernate.connection.url" value="jdbc:postgresql://localhost/testDB"/>
    			<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
    			<property name="hibernate.connection.username" value="standard"/>
    			<property name="hibernate.connection.password" value="standard"/>
    
    		</properties>
    	</persistence-unit>
    </persistence>

    The test client:

    Code:
    public class UserDaoTest {
    
    	private BeanFactory jpaBeanFactory = null;
    
    	@Before
    	public void setUp() throws Exception {
    		//hibernateBeanFactory = new XmlBeanFactory(new ClassPathResource("spring3-hibernate.xml"));
    		jpaBeanFactory = new XmlBeanFactory(new ClassPathResource("spring3-entity.xml"));//spring3-entity spring3-jpa2.xml
    	}
    
    
    	@Test
    	public void testJpaPlainUserDAO() {
    		UserDAO userDAO = (UserDAO)jpaBeanFactory.getBean("jpaPlainUserDAO");
    		log.debug(userDAO.getClass().getName());
    
    		User u = userDAO.findByPrimaryKey(new Long(1));
    		
    		log.debug("user="+u); 
    		// u is null after DB was completely refreshed making shure that PK value 1 is the PK of the
    		// not existing User :-(
    	}
    
    
    	@Test
    	public void testJpaPlainUserDAOManual() {
    		UserDAO userDAO = (UserDAO)jpaBeanFactory.getBean("jpaPlainUserDAO");
    		log.debug(userDAO.getClass().getName());
    		
    		JpaTransactionManager transactionManager = (JpaTransactionManager)jpaBeanFactory.getBean("transactionManager");
    		TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    		User user = newUser();
    		userDAO.createUser(user);
    		transactionManager.commit(status);
    		
    		User u = userDAO.findByPrimaryKey(new Long(1));
    
    		log.debug("user="+u);
    		// u is NOT null
    	}
    }

    When I use manual transaction management, the User entity is inserted in method testJpaPlainUserDAOManual.
    I clearly prefer the spring transaction managed solution. Unfortunately, the Hibernate enabled logging
    issues no insert log statement:

    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')

    4 times because of 1 user and 3 address entities, but no Hibernate: insert into ...


    In contrast to the testJpaPlainUserDAOManual method:

    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: insert into table_user (creationdate, firstname, lastname, id) values (?, ?, ?, ?)
    ...


    What is wrong with my configuration? I read already countless forum posts with very similar problems,
    tutorials and books, but I can't figure out what is missing.


    Kind regards,

    Andreas

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    I suggest chapter 3 of the reference guide.

    You are using a BeanFactory where you should be using an ApplicationContext (chapter 3 explains the difference between both).

    This question has been answered numerous times before (by me alone) so the forum search should really provide the answer.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Nov 2009
    Location
    Poznań, Poland
    Posts
    23

    Default

    I have a similar problem and cannot find any accurate answer to it (search won't help, I cannot find answer in documentation too), so your help will be appreciated, though I understand I might miss some basics. For the reference my test-config.xml looks like this:

    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:context="http://www.springframework.org/schema/context"
    		xmlns:tx="http://www.springframework.org/schema/tx"		
    		xsi:schemaLocation="http://www.springframework.org/schema/beans
    							http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    							http://www.springframework.org/schema/context
    							http://www.springframework.org/schema/context/spring-context-3.0.xsd
    							http://www.springframework.org/schema/tx
    							http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    	
    	<bean id="swDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="com.p6spy.engine.spy.P6SpyDriver" />
    		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:SOMESCHEMA"/>
    		<property name="username" value="user"/>
    		<property name="password" value="password"/>	
    	</bean>
    	
    	<bean id="entityManagerFactory"
    		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    		<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
    		<property name="dataSource" ref="swDataSource"/>
    		<property name="jpaVendorAdapter">
    			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    		</property>
    	</bean>
    	
    	<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
    	
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" autowire="byName">
    		<property name="entityManagerFactory" ref="entityManagerFactory"/>
    		<property name="dataSource" ref="swDataSource"/>
    		<property name="jpaDialect" ref="jpaDialect"/>
    	</bean>
    	
    	<tx:annotation-driven transaction-manager="transactionManager" />
    		
    	<bean id="kartotekaStudentaService" class="put.datalayer.kartoteka.impl.KartotekaStudentaServiceImpl" autowire="byName" />
    		
    </beans>
    Class KartotekaStudentaServiceImpl does implement KartotekaStudentaService interface which is annotated with @Transactional.

    I wrote the test:
    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "/META-INF/spring/test-config.xml" })
    @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public class KartotekaStudentaServiceImplTest {
    
    	private static final Logger log = Logger.getLogger(KartotekaStudentaServiceImplTest.class);
    
    	@Autowired
    	KartotekaStudentaService kartotekaStudentaService;
    
    	@Test
    	@Rollback(false)
    	public void shouldGetOredCollection() {
    		KartotekaStudenta ks = new KartotekaStudenta();
    		ks.setIndeks("TestStudent" + 1);
    		ks.setNazwisko("Jenkins");
    		ks.setImie("Leeroy");
    		ks.setUrodzeniaData(new GregorianCalendar(87, 6, 21).getTime());
    		Miejscowosc urMi = new Miejscowosc();
    		urMi.setId(969400);
    		ks.setUrodzeniaMiejsce(urMi);
    		ks.setCudzoziemiec(false);
    		Panstwo pa = new Panstwo();
    		pa.setId("PL");
    		ks.setPanstwo(pa);
    		ks.setDataPierwszejImmatrykulacji(new Date());
    		ks.setAktywny(true);
    		ks.setSwiadczeniaPrzelewem(true);
    		KartotekaStudenta mks = kartotekaStudentaService.merge(ks);
    		// kartotekaStudentaService.persist(mks);
    	}
    }
    When I run the test there are no errors, transaction is commited but no data is saved (no insert is made after calling merge). I've even tried to persist the object returned by merge, and it does persist (method throws no error) but no insert is called on DB. i've checked everything with db logs, hibernate query logging and p6spy. It won't even try to call insert on database, which would result in errors if no transaction was found.
    What can I do to deal with that problem?

  4. #4
    Join Date
    Dec 2010
    Posts
    2

    Default

    I have a very same problem with PostgreSQL 8.4 on Ubuntu 10.10.
    Strangely I "fixed" it by using Oracle 10g XE (insert/delete works).

    May it is somehow related to JDBC driver itself...?

    JBOSS 6.0 CR1
    JPA 2.0 / Hibernate 3.6.0 Final
    Spring 3.0.5 release


    Any idea how to "debug" it?

  5. #5

    Default

    Quote Originally Posted by rstribrn View Post
    I have a very same problem with PostgreSQL 8.4 on Ubuntu 10.10.
    Strangely I "fixed" it by using Oracle 10g XE (insert/delete works).

    May it is somehow related to JDBC driver itself...?

    JBOSS 6.0 CR1
    JPA 2.0 / Hibernate 3.6.0 Final
    Spring 3.0.5 release


    Any idea how to "debug" it?
    Hi rstribrn I want to setup an environment like yours but using Windows as the OS. Can you let me know how do you set that up? I am never able to use Spring 3.0.5 release and JPA 2.0/Hibernate 3.6.0 Final together in JBoss 6.0 because of heaps of errors I get. I also have some legacy EJB 2.0 entity beans which I will be migrating to JPA 2 later but for the time being I will leave them there.
    Can you please show me the configuration files? Thank you.
    Last edited by newguy; Dec 23rd, 2010 at 06:51 PM.

  6. #6
    Join Date
    Dec 2010
    Posts
    2

    Default

    Quote Originally Posted by newguy View Post
    Hi rstribrn I want to setup an environment like yours but using Windows as the OS. Can you let me know how do you set that up? I am never able to use Spring 3.0.5 release and JPA 2.0/Hibernate 3.6.0 Final together in JBoss 6.0 because of heaps of errors I get. I also have some legacy EJB 2.0 entity beans which I will be migrating to JPA 2 later but for the time being I will leave them there.
    Can you please show me the configuration files? Thank you.
    Hi, I've decided to share my example project so you can find the source codes here.
    Application context files: **/app-prod-*.xml, most important ones are under trunk/JPA-Spring-JSF/CZU-PEF-DataModelling/ejb-backend/src/main/resources).

    Note: I'm still working on it but the persistence itself is working quite fine...Have fun.

  7. #7

    Default

    Quote Originally Posted by rstribrn View Post
    Hi, I've decided to share my example project so you can find the source codes here.
    Application context files: **/app-prod-*.xml, most important ones are under trunk/JPA-Spring-JSF/CZU-PEF-DataModelling/ejb-backend/src/main/resources).

    Note: I'm still working on it but the persistence itself is working quite fine...Have fun.
    Thank you rstibrn. I have already managed to deploy my JPA2 + EJB 2 + spring 3.0 project to JBoss 6.0.0 Final and I finally can have a good holiday. I wish everyone a happy new year too.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •