JUnit - org.hibernate.SessionException: Session is closed

前提是你 提交于 2020-12-13 18:05:53

问题


I am facing a common error with Hibernate sessions : javax.persistence.TransactionRequiredException: Executing an update/delete query.

I found a solution, make my test class extends AbstractTransactionalJUnit4SpringContextTests but I don't understand why is it necessary.

I try to set junit (4.11 version) tests on my project.

  • My test class :

_

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:config/ioc/application-context-spring-test.xml" })
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
@TransactionConfiguration(transactionManager = "myTxManager")
@Transactional
public class UserPreferenceDAOTest extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    private UserPreferenceDAO dao;

    @Test
    @Transactional
    public void test() {

        try {
            SQLQuery query = dao.createSQLQuery("SELECT 1 from dual");
            query.uniqueResult();
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
}

The UserPreferenceDAO is instantiated. It is the query.uniqueResult(); line that throws the javax.persistence.TransactionRequiredException exception.

  • application-context-spring.xml :

Contains configuration for database access :

    <!-- To precise the persistence configuration name file -->
    <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="persistenceXmlLocations">
            <list>
                <value>classpath*:META-INF/persistence-web.xml</value>
            </list>
        </property>
        <property name="defaultDataSource" ref="dataSource" />
    </bean>

    <!-- EntityManagerFactory definition : JPA one -->
    <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="persistenceUnitManager" />
        <property name="persistenceUnitName" value="myPersistenceUnit" />
    </bean>

    <!-- Transaction Manager definition : JPA one-->
    <bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="myEmf" />
    </bean>

    <!-- Enable the annotation usage (bean injection for instance) -->
    <context:annotation-config />

    <!-- Enable annotation usage for transaction -->
    <tx:annotation-driven transaction-manager="myTxManager" proxy-target-class="false"/>

    <!-- Enterprise layer's dependencies -->
    <!-- UserPreferenceDAO bean statement here -->
    <import resource="classpath:ioc/0-model-enterpriselayer-dependencies.xml"/>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@myurl:1522:TD11P15A" />
        <property name="username" value="user" />
        <property name="password" value="pwd" />
    </bean>
  • persistence.xml :

_

<persistence>

    <persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!-- with Annotations -->
        <class>com.airfrance.padme.server.entity.UserPreference</class>
        <!-- etc... (all my entities) -->
        <properties>
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        </properties>
    </persistence-unit>
</persistence>

Most tutorials I found doesn't use this AbstractTransactionalJUnit4SpringContextTests class. Example here : http://www.concretepage.com/spring-4/spring-4-junit-4-annotation-example

Where am I wrong ?

Thanks


回答1:


According to the doc AbstractTransactionalJUnit4SpringContextTests includes the following test execution listeners:

  • ServletTestExecutionListener
  • DependencyInjectionTestExecutionListener
  • DirtiesContextTestExecutionListener
  • TransactionalTestExecutionListener
  • SqlScriptsTestExecutionListener

If you don't want to extend from AbstractTransactionalJUnit4SpringContextTests and yet you still want the transactional behaviour just add the TransactionalTestExecutionListener to your listeners:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})

TransactionalTestExecutionListener's javadoc:

TestExecutionListener that provides support for executing tests within test-managed transactions by honoring Spring's @Transactional annotation.



来源:https://stackoverflow.com/questions/30349265/junit-org-hibernate-sessionexception-session-is-closed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!