Я написал несколько тестовых примеров для нашего проекта на основе Spring-MVC.Поскольку проект огромен, мы используем 2 источника данных и 2 менеджера транзакций, и оба общаются с одной и той же базой данных, используя HikariPool.При использовании веб-приложения, если я сохраняю объект с 1-м источником данных и извлекаю его с 2-м источником данных, он работает нормально, но не при работе mvn test
.
Есть идеи?
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml",
"file:src/main/webapp/WEB-INF/spring/root-context.xml", "file:src/main/webapp/WEB-INF/spring/appServlet/security-applicationContext.xml"})
@Ignore
@WebAppConfiguration
@Transactional
public class TestingController {
//All autowired dependencies
}
Уровень DAO, где код не работает:
@Repository
@Transactional
public class GroupNotesDAOImpl implements GroupNotesDAO {
@Autowired
@Qualifier(value = "sessionFactory_origin")
private final SessionFactory sessionFactory;
@Autowired
@Qualifier(value = "sessionFactory_extended")
private final SessionFactory sessionFactory_extended;
@Override
public GroupNotes getGroupNoteByIdExtended(int id){
Session session = this.sessionFactory_extended.getCurrentSession();
System.out.println("Id of note is "+id);
// Getting null below, even though the object exists, id is non-zero
return (GroupNotes) session.get(GroupNotes.class, id);
}
}
Внутри браузера все работает просто отлично.Расширенный источник данных предназначен для долго работающих сервисов.
Сохранить код DAO:
@Override
public int saveGroupNoteAndReturnId(GroupNotes mnotes, int msectionid) {
Session session = this.sessionFactory.getCurrentSession();
if(mnotes.getCanvasId()!=0) {
GroupSection groupSection = (GroupSection) session.get(GroupSection.class, msectionid);
groupSection.getSectionsnotes().add(mnotes);
mnotes.setOwnednotes(groupSection);
int saveId = (Integer) session.save(mnotes);
session.flush();
return saveId;
}else {
return 0;
}
}
Контрольные примеры:
// First test calls the save method
groupNotes = TestUtils.createGroupNotes("testtag", "testtext", loggedInUser.getId());
groupNotes.setCanvasId(mcanvasId);
int noteId = this.groupNotesService.saveGroupNoteAndReturnId(groupNotes, msectionId);
assert noteId!=0;
The 2nd test calls to retrieve the object for duplicating. As duplication is a long run process, it's executed with extended transaction manager
int success =this.groupNotesService.duplicateGroupNote(noteId, msectionId, groupId, true,true,4.0,false);
assert(success!=0);
root-context.xml:
<beans:bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<beans:property name="dataSourceClassName" value="org.USERNAMEql.ds.PGSimpleDataSource"/>
<beans:property name="maxLifetime" value="30000" />
<beans:property name="idleTimeout" value="40000" />
<beans:property name="connectionTimeout" value="60000"/>
<beans:property name="maximumPoolSize" value="6"/>
<beans:property name="dataSourceProperties">
<beans:props>
<beans:prop key="url">jdbc:USERNAMEql://localhost:PORT_NUMBER/DB_NAME</beans:prop>
<beans:prop key="user">USERNAME</beans:prop>
<beans:prop key="password">PASSWORD</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory_origin"/>
</beans:bean>
<beans:bean id="sessionFactory_origin" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="com.ourapp.spring.model"/>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.jdbc.lob.non_contextual_creation">true</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.USERNAMEQL9Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="cache.use_second_level_cache">true</beans:prop>
<beans:prop key="cache.use_query_cache">true</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<beans:prop key="show_sql">false</beans:prop>
<beans:prop key="connection.release_mode">after_statement</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="extended_transactions_data_source" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<beans:property name="dataSourceClassName" value="org.USERNAMEql.ds.PGSimpleDataSource"/>
<beans:property name="maximumPoolSize" value="3" />
<beans:property name="maxLifetime" value="30000" />
<beans:property name="idleTimeout" value="40000" />
<beans:property name="connectionTimeout" value="60000"/>
<beans:property name="dataSourceProperties">
<beans:props>
<beans:prop key="url">jdbc:USERNAMEql://localhost:PORT_NUMBER/DB_NAME</beans:prop>
<beans:prop key="user">USERNAME</beans:prop>
<beans:prop key="password">PASSWORD</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager_extended"/>
<beans:bean id="transactionManager_extended" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory_extended"/>
</beans:bean>
<beans:bean id="sessionFactory_extended" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="extended_transactions_data_source" />
<beans:property name="packagesToScan" value="com.ourapp.spring.model"/>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.jdbc.lob.non_contextual_creation">true</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.USERNAMEQL9Dialect</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<beans:prop key="hibernate.jdbc.batch_size">25</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="cache.use_second_level_cache">false</beans:prop>
<beans:prop key="cache.use_query_cache">false</beans:prop>
<beans:prop key="hibernate.order_updates">true</beans:prop>
<beans:prop key="show_sql">false</beans:prop>
<beans:prop key="connection.release_mode">after_statement</beans:prop>
</beans:props>
</beans:property>
</beans:bean>