我使用简单的“helloWorld”ish应用程序来学习使用AOP的Spring,Hibernate和事务管理。但是没有按预期工作。我在事务管理中遇到异常。详情如下: -
Spring version 4.3.8
Hibernate version 5.2.10
HSQL DB version 2.3.4
Spring.xml如下所示
<?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: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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- Enable Annotation based Declarative Transaction Management -->
<tx:annotation-driven proxy-target-class="true" mode="aspectj"
transaction-manager="transactionManager" />
<!-- THIS IS COMMENTED. Without commenting same result. I TRIED USING HibernateTransactionManager. still got same result. -->
<!--
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:file:C:/ProjectRelated/softwares/hsqldb-2.3.4/hsqldb/data/FirstFile"/>
<property name="username" value="sa"/>
<property name="password" value="sys"/>
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" >
<array>
<value>com.kaushik.winnersoft.data</value>
</array>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id="customerDAO" class="com.kaushik.winnersoft.dao.CustomerDAOImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"></property>
</bean>
<bean id="customerManager" class="com.kaushik.winnersoft.CustomerManagerImpl">
<property name="customerDAO" ref="customerDAO"></property>
</bean>
DAOImpl类是
public class CustomerDAOImpl implements CustomerDAO {
private HibernateTemplate hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
@Override
@Transactional
public void create(Customer customer) {
System.out.println("in dao creating");
hibernateTemplate.save(customer);
System.out.println("in dao creating done");
}
我得到如下输出
Doing
in dao creating
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
at org.springframework.orm.hibernate5.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1165)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:643)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:640)
at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:359)
at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:326)
at org.springframework.orm.hibernate5.HibernateTemplate.save(HibernateTemplate.java:640)
at com.kaushik.winnersoft.dao.CustomerDAOImpl.create(CustomerDAOImpl.java:27)
at com.kaushik.winnersoft.CustomerManagerImpl.createCustomer(CustomerManagerImpl.java:20)
at com.kaushik.winnersoft.SpringTest.main(SpringTest.java:14)
答案
基于M. Denium在下面给出的评论;我做了以下更改并且工作正常。
1)使用HibernateTransactionManager而不是DataSourceTransactionManager
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
2)在删除模式=“aspectj” 所以它看起来像
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
答案 0 :(得分:1)
我发现您的配置存在问题
PlatformTransactionManager
mode="aspectj"
是否正确。 首先,您需要使用支持持久性技术的PlatformTransactionManager
,因为您使用的是Hibernate 5,您需要使用org.springframework.orm.hibernate5.HibernateTransactionManager
而不是DataSourceTransactionManager
。 (后者适用于仅执行普通JDBC事务的应用程序)。
从<tx:annotation-driven />
移除mode="aspectj"
因为我怀疑你实际上并没有使用完整的AspectJ,而是依靠普通的Spring来为你做这件事。
专家提示:而不是使用自{Hibernate 3.0.1以后不再推荐的HibernateTemplate
,而是使用SessionFactory
代替getCurrentSession
。这将允许您编写简单的Hibernate daos。正如reference guide中所述。