问题
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