среды: 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>
при введении объекта sessionFactory в ваш userDaoImpl вы не должны использовать область действия в качестве прототипа, тогда весна создаст новый sessionFactory obj за каждый новый вызов. sessionFactory obj должен быть одним для каждого приложения – tinku
Проблема в том, что вы не используете 'getCurrentSession', что и должно использовать иначе, это не сработает. Вы не должны возиться с открытием/закрытием сессий самостоятельно, если вы это делаете, вам также нужно управлять транзакциями самостоятельно. –
Вы пытаетесь ввести объект sessionFactory в свой класс userDaoImpl, вместо этого вы должны вводить его непосредственно в свой общий класс либо с помощью аннотации, либо с помощью сопоставления xml. – tinku