Spring 테스트를 사용하여 SQL 스크립트를 실행하면 변경 사항이 있습니다
-
12-12-2019 - |
문제
Spring을 사용하여 JUnit 테스트에서 SQL 스크립트를 실행하려고합니다. 이 스크립트는 테스트에 대한 데이터를 설정하는 데 사용됩니다. 그러나 스크립트가 실행되면 각 테스트 후에 스크립트의 삽입물이 커밋됩니다. Spring 문서는 DDL로 롤백을 기대하지 말고 내 스크립트의 모든 것이 DML입니다. 포함하는 모든 것은 삽입문을 삽입하고 마지막 삽입 ID (@blah= last_insert_id ()를 설정합니다).
뭔가 잘못 구성되어 있습니까? 나는 이것을 mysql 데이터베이스에 대해 사용하고있다. 우리의 구성은 다음과 같습니다 :
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext.xml" })
@TransactionConfiguration(defaultRollback = true)
public class OrderTestCase extends AbstractTransactionalJUnit4SpringContextTests {
@Before
public void runSql() {
String fileName = StringUtils.replace(getClass().getName(), ".", "/") + ".sql";
Resource resource = applicationContext.getResource(fileName);
if (resource.exists()) {
executeSqlScript(fileName, false);
} else {
LOGGER.debug("Resource doesn't exist: {}", resource);
}
}
@Test
public void testLoadOrders() {
Collection<Order> orders= dao.findAll();
assertTrue(orders.size() == 3);
}
}
.
여기에 몇 가지 연구에 따라 일어나고있는 것이 일어나고있는 것입니다. executesqlscript의 첫 번째 호출은 별도의 트랜잭션에서 실행 중입니다. Spring의 SimpleJDBCTemplate.Update 메서드는 ExecuteQLScript에 의해 호출됩니다. 이 때문에 연결 풀에서 얻은 JDBC 연결에 범위가 지정되므로 DB에 대한 후속 액세스에 대해 동일한 연결을 얻을 수 없으므로 동일한 트랜잭션에서 실행되도록 보장 할 수 없습니다. 트랜잭션 메이너 또는 (최대 절전 세션 공장)을 통해 모든 DB 작업을 수행하는 경우 내부가 트랜잭션을 전송하는 방법 때문에 작동합니다. 내 옵션은 다음과 같습니다.
-
SimpleJdbcTemplate.Update를 실행하는 방법과 다음 실제 코드는 동일한 거래에서 테스트하고 있습니다. 나는 이것을 할 수 있다고 생각합니다. 그러나 지금까지 나의 노력은 열매 맺지 않았습니다.
-
모든 테스트 데이터를 SessionFactory를 통해 설정합니다. 따라서 JDBC를 통해 SQL 스크립트를 직선 SQL 스크립트를 실행하는 대신 모델 객체를 채우고 Hibernate DAO를 통해이를 유지합니다.
나는 여기에서 올바른 궤도에 있습니까? 누구든지 더 이상 지침을 제공 할 수 있습니까?
해결책 2
INTITEMANAGERFACTORY의 선언에 다음 'JPAVENDORADAPTER'를 추가하여이를 해결할 수있었습니다.
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
. 다른 팁
DB 연결에서 자동 커밋을 활성화 할 수 있습니다.
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="defaultAutoCommit" value="false"/>
</bean>
.
JDBC URL 에서이 인수를 전달할 수도 있습니다.