2016-07-15 7 views
0

среды: Eclipse, Keppler, причал 7.5.1, Spring 3.2.1, Hibernate 4.2.5, Oracle 11Spring транзакция не запускается

Проблема: зимовать объект сохраняет не применяется к базе данных физически

Причиной проблемы может быть: нет активных транзакций

Вопрос: Почему транзакция не начинается?

Примечание: если я изменил openSession() на getCurrentSession(), все будет работать. Начало транзакции & объект сохраняет физически DB.


GenericDaoImpl:

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, 
       value = "transactionManager") 
public abstract class GenericDaoImpl<T, ID extends Serializable> implements GenericDao<T, ID> { 

    private Class<T> persistentClass; 

    protected SessionFactory sessionFactory; 

    @Override 
    public T addEntity(T entity) { 

     Session session = null; 

     try { 
      session = sessionFactory.openSession(); 

      session.save(entity); 
     } catch (Exception e) { 
      e.printStackTrace();  
     } finally { 

      if(session != null){ 
       Transaction t = session.getTransaction();    
System.out.println("Transaction().isActive()......." + session.getTransaction().isActive());    
System.out.println("before: session.isOpen() " + session.isOpen() + " trx wasCommitted " + t.wasCommitted()); 

       session.close(); 

System.out.println("after: session.isOpen() " + session.isOpen() + " trx wasCommitted" + t.wasCommitted());    
     } 
    } 

    return entity; 
} 

UserDaoImpl простирающиеся GenericDaoImpl:

@Component 
@Scope("prototype") 
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, value = "transactionManager") 
public class UserDaoImpl extends GenericDaoImpl<User, Long> implements UserDao { 
    . 
    . 
    } 

После следующий код выполняется под названием:

userDao.addEntity(user); 

журналы напечатаны ниже:

Transaction().isActive().......false 
before: session.isOpen() true trx wasCommitted false 
after: session.isOpen() false trx wasCommittedfalse 

журналы транзакций:

[2016-07-15 10:42:04,567][DEBUG] Adding transactional method 'addEntity' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 'transactionManager' 

databaseContext.xml:

<bean class="com.blabla.dao.local.implementations.UserDaoImpl" 
    scope="prototype" name="userDao"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<tx:annotation-driven /> 

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="packagesToScan" 
     value="com.blabla.model.local,com.blabla.model.authorization, com.blabla.model.authentication" /> 
    <property name="entityInterceptor"> 
     <bean class="com.blabla.listeners.EntityInterceptor" /> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.transaction.flush_before_completion">true</prop> 
      <prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop> 
      <prop key="hibernate.connection.driver_class">${jdbc.driver}</prop> 
      <prop key="hibernate.connection.url">${jdbc.url}</prop> 
      <prop key="hibernate.connection.username">${jdbc.user}</prop> 
      <prop key="hibernate.connection.password">${jdbc.password}</prop> 
     </props> 
    </property> 
</bean> 
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" 
    destroy-method="close"> 
    <property name="driverClassName" value="${jdbc.driver}" /> 
    <property name="url" value="${jdbc.url}" /> 
    <property name="username" value="${jdbc.user}" /> 
    <property name="password" value="${jdbc.password}" /> 
    <property name="initialSize" value="5" /> 
    <property name="maxActive" value="10" /> 
</bean> 
+0

при введении объекта sessionFactory в ваш userDaoImpl вы не должны использовать область действия в качестве прототипа, тогда весна создаст новый sessionFactory obj за каждый новый вызов. sessionFactory obj должен быть одним для каждого приложения – tinku

+0

Проблема в том, что вы не используете 'getCurrentSession', что и должно использовать иначе, это не сработает. Вы не должны возиться с открытием/закрытием сессий самостоятельно, если вы это делаете, вам также нужно управлять транзакциями самостоятельно. –

+0

Вы пытаетесь ввести объект sessionFactory в свой класс userDaoImpl, вместо этого вы должны вводить его непосредственно в свой общий класс либо с помощью аннотации, либо с помощью сопоставления xml. – tinku

ответ

0

В вашем примере это в значительной степени очевидно, что spring ручки гибернации сессии и сделки:

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

So вы не можете использовать thi с:

session = sessionFactory.openSession(); 

Потому что вы открываете новую сессию спящего режима и весна ничего не знает об этом.

Использование: sessionFactory.getCurrentSession() означает, что spring будет обрабатывать все, что находится за сценой, с вашей надлежащей конфигурацией.

+0

спасибо за ваше объяснение. Я вижу это сейчас. –

Смежные вопросы