vvekselva
vvekselva

Reputation: 823

Tranaction Manager in Spring JPA DAO

I've used the following configuration in spring and JPA,

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">


<bean id="entityManger"
    class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JPA-01" />
</bean>

<bean id="dao" class="springdao.MessageDAO" />

</beans>

and my persistence.xml is,

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="JPA-01">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.archive.autodetection" value="class, hbm" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/Hibernate" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="password" />
            <property name="hibernate.c3p0.min_size" value="5" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="300" />
            <property name="hibernate.c3p0.max_statements" value="50" />
            <property name="hibernate.c3p0.idle_test_period" value="3000" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <!-- <property name="hibernate.hbm2ddl.auto" value="create" />
             -->
        </properties>

    </persistence-unit>
</persistence>

and my junit is,

package test;

import junit.framework.Assert;
import model.Message;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import dao.MessageDAO;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:SpringDAOTest.xml"})
public class SpringDAOTest {


    @Autowired
    springdao.MessageDAO dao;





    @Test
    public void testGetMessageById() {
        Message message = dao.getMessageById("1");
        Assert.assertNotNull(message);
        System.out.println(message);
    }

    @Test
    public void testPersistMEssage() {
        Message message = new Message();
        message.setMessage("Hello World This is the second Message");
        dao.persistMessage(message);

    }

    @Test
    public void testUpdateMessage() {
        String updatedMessage = "Updated Message for ID 1";
        dao.updateMessage(updatedMessage, 1);

    }

    // TODO updateMessageID
    @Test
    public void testUpdateMessageID() {
        String updatedMessage = "Updated Message for ID 1 with 25";
        dao.updateMessageID(updatedMessage, 1);

    }

}

I've following questions,

  1. I've autowired the persistence context. I want to assert that the current persistent context is associtated or not?
  2. I've not used the transaction manager configured in the applicationcontext.xml. Just by annotating the classes, I'm able to configure transactions to the services.
  3. I want to get the entity transaction id, so that I want to assert that for the entire service (which involves a lot of daos) uses the same transaction.

Upvotes: 0

Views: 101

Answers (2)

Shailendra
Shailendra

Reputation: 9102

As you are using entity manager as the data-access API you can use following transaction manager configuration

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

By default this transaction manager picks up the datasource bean if named "dataSource" and "entityManagerFactory". This transaction manager variety binds the entity manager from the specified entitymanager factory with the current thread. Also it would be worthwhile to have a look at its documentation.

Upvotes: 0

Kalyan
Kalyan

Reputation: 1939

1) Provide a getter method for EntityManager in your MessageDAO and use assertNotNull (Although not advisable and not required to test this scenario; you should be testing only your business logic and trust the framework will correctly associate the EntityManager)

2) Reading data from database doesn't require transaction. However, writing data to database does require transaction. Therefore you need to configure a transaction manager for your persistent operation like below

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

You can make a method execute under a transaction in two ways

  • XML configuration
  • @Transactional annotation

Annotating your method using @Transactional without a TransactionManager will silently ignore it.

3) I'm not aware of retrieving a transaction id. However, the primary intention of using a framework like Spring is that someone has already tested infrastructure code for you and you can concentrate on testing only your business logic. Trying to retest may not be a good idea.

Upvotes: 1

Related Questions