мы боролись с этим в течение нескольких недель.
первый код,
<?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"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.nmsc" />
<tx:annotation-driven proxy-target-class="true"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
мой класс дао
@SuppressWarnings("unused")
@Repository("com.nmsc.hibernateDAO.SSOUserDAO")
@Transaction
public class SSOUserDAO implements SSOUserDAOSPI{
private static Logger logger = Logger.getLogger(SSOUserDAO.class);
@Autowired(required=true)
private SessionFactory sessionFactory;
@Transactional
public Integer saveUpdate(SSOUser user) {
sessionFactory.getCurrentSession().saveOrUpdate(user);
return user.getIdUser();
}
хорошо, теперьесли в моем junit я делаю это
@Test
@Transaction
public void testStoreRetrieve() {
SSOUserDAOSPI userDAO = ServiceProviderContext.find(SSOUserDAOSPI.class);
System.out.println("test");
userDAO.deleteAllInUserTable();
SSOUser user = buildTestUser();
Integer id = userDAO.saveUpdate(user);
user.setIdUser(id);
// retrieve the user from the database
SSOUser retrievedUser = userDAO.getByID(id);
checkResults(user, retrievedUser);
}
удаление пользователей работает просто найти, но когда это делает saveupdate, выполнение просто зависает.без ошибок, без ничего, просто зависает, пока вы не убьете процесс.
аналогично, если я сделаю
Integer id = userDAO.saveUpdate(user);
, он будет отлично работать и вставит пользователя, но если я сделаю
Integer id = userDAO.saveUpdate(user);
Integer id2 = userDAO.saveUpdate(user2);
вставит первого пользователя и остановит второго.он сделал нечто подобное, прежде чем мы попытались реализовать пружинные транзакции (что мы должны были сделать для других частей системы), только он вставил бы пользователя, но не user2, но файл журнала гибернации показал бы, что он действительно вставил второго пользователя,
Я не могу сказать, что-то с hibernate или postgres.я сомневаюсь, что это что-то, что делает весна, потому что это было похоже еще до того, как мы добавили весну на картинку.
РЕДАКТИРОВАТЬ ПОПРОБОВАТЬ ДВА
хорошо, вот мой класс дао
@SuppressWarnings("unused")
@Repository
public class SSOUserDAO implements SSOUserDAOSPI{
private static Logger logger = Logger.getLogger(SSOUserDAO.class);
@Autowired(required=true)
private SessionFactory sessionFactory;
public Integer saveUpdate(SSOUser user) {
sessionFactory.getCurrentSession().saveOrUpdate(user);
return user.getIdUser();
}
public void deleteAllInUserTable() {
// delete everything in the table to run the test
logger.debug("beginning delete");
if (sessionFactory == null){
logger.debug("session factory null");
} else
logger.debug("sessionfactory not null");
Query q = sessionFactory.getCurrentSession().createQuery("delete from SSOUser");
q.executeUpdate();
}
и я изменил свой тест на этот
@Test
@Transactional(propagation=Propagation.REQUIRED)
public void testStoreRetrieve() {
SSOUserDAOSPI userDAO = ServiceProviderContext.find(SSOUserDAOSPI.class);
System.out.println("test");
userDAO.deleteAllInUserTable();
SSOUser user = buildTestUser();
Integer id = userDAO.saveUpdate(user);
user.setIdUser(id);
// retrieve the user from the database
SSOUser retrievedUser = userDAO.getByID(id);
checkResults(user, retrievedUser);
}
, который, если я правильно вас понимаю, это именно то, что вы делаете (за исключением того факта, что его джунт запускает его), но я получаю то же самоеисключение.мы, вероятно, перейдем к весенним тестам в будущем, но на данный момент мне нужно запустить существующие тесты, все 300 или около того.
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
at com.nmsc.hibernateDAO.SSOUserDAO.deleteAllInUserTable(SSOUserDAO.java:121)
at com.nmsc.hibernateDAO.SSOUserDAO_Test.testStoreRetrieve(SSOUserDAO_Test.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
часть, которая сводит меня с ума, - моя инициализацияжурнал показывает это
Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
1651 [main] DEBUG org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - Autowiring by type from bean name 'SSOUserDAO' to bean named 'sessionFactory'
1651 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
1653 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'SSOUserDAO'
, которое говорит мне, что Spring полностью знает, что компонент управляется менеджером транзакций.поэтому, когда я получаю экземпляр bean-компонента, менеджер транзакций должен это знать, но, похоже, он этого не знает.
EDIT TRY THREE
ок, я изменилсямой тест на это
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{
"classpath:transaction-service.xml"
})
public class SSOUserDAO_Test extends JunitHelperClass {
private static Logger logger = Logger.getLogger(SSOUserDAO_Test.class);
@Resource
SSOUserDAOSPI userDAO;
@Test
@Transactional(propagation=Propagation.REQUIRED)
public void testStoreRetrieve() {
//SSOUserDAOSPI userDAO = ServiceProviderContext.find(SSOUserDAOSPI.class);
System.out.println("test");
userDAO.deleteAllInUserTable();
SSOUser user = buildTestUser();
Integer id = userDAO.saveUpdate(user);
user.setIdUser(id);
// retrieve the user from the database
SSOUser retrievedUser = userDAO.getByID(id);
checkResults(user, retrievedUser);
}
, и я возвращаюсь к той же блокировке, когда он пытается вставить пользователя.удаление работает нормально, пользователь проваливается.