我正在使用Spring和Hibernate进行现有项目,并且感到困惑,因为我得到了
org.springframework.dao.InvalidDataAccessApiUsageException:只读模式(FlushMode.MANUAL)中不允许写操作:将Session转换为FlushMode.COMMIT / AUTO或从事务定义中删除“ readOnly”标记。
尝试保存对象时出现错误,但我仍然找不到确切的错误。
有一个使用注释的服务层@Service
和一种save
应该是事务性的方法,因此使用进行了注释@Transactional(readOnly = false)
。对我来说,这意味着spring应该自己处理交易。
@Service
public class LadyService {
Logger log = Logger.getLogger(LadyService.class);
@Autowired
private PictureDAO pictureDao;
@Autowired
private LadyDAO ladyDao;
@Autowired
private AddressDAO addressDao;
@Transactional(readOnly = false)
public void save(Lady lady) {
Address a = addressDao.getExistingAddress(lady.getAddress());
if (a == null) {
a = addressDao.save(lady.getAddress());
}
lady.setAddress(a);
ladyDao.save(lady);
pictureDao.savePictures(lady.getPictures());
}
在中保存时发生错误AddressDAO
。注释为@Repository
。
@Repository
public class AddressDAO extends HibernateDaoSupport {
public Address save(Address address) {
getHibernateTemplate().save(address); <-- write not permitted error happens here
return address;
}
@SuppressWarnings({ "unchecked" })
public Address getExistingAddress(Address address) {
DetachedCriteria cd = DetachedCriteria.forClass(Address.class);
cd.add(Restrictions.eqOrIsNull("administrative_area_level_1",
address.getAdministrative_area_level_1()));
cd.add(Restrictions.eqOrIsNull("administrative_area_level_2",
address.getAdministrative_area_level_2()));
List<Address> result = (List<Address>) getHibernateTemplate()
.findByCriteria(cd);
if (result.isEmpty()) {
return null;
} else {
return (Address) result.get(0);
}
}
}
我以为发生了什么事,就是@Transactional
让spring在服务层上为保存创建一个会话和一个事务,并且在DAO中,休眠模板将获得spring管理的当前会话和事务,并使用它来保存对象。
但是,错误消息使我认为我的服务方法和dao方法不在同一事务中。
在servlet-context.xml中,有以下语句:
<annotation-driven />
<context:component-scan base-package="com.kog.fable" />
<beans:bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="myDataSource" />
<beans:property name="packagesToScan">
<beans:array>
<beans:value>com.kog.fable.**.*</beans:value>
</beans:array>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<!-- create, validate, update -->
<beans:prop key="hibernate.hbm2ddl.auto">create</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<beans:prop key="hibernate.connection.pool_size">10</beans:prop>
<beans:prop key="hibernate.connection.autocommit ">false</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="mySessionFactory" />
</beans:bean>
<beans:bean id="addressDAO" class="com.kog.fable.dao.AddressDAO">
<beans:property name="sessionFactory" ref="mySessionFactory" />
</beans:bean>
<beans:bean id="ladyDAO" class="com.kog.fable.dao.LadyDAO">
<beans:property name="sessionFactory" ref="mySessionFactory" />
</beans:bean>
<beans:bean id="pictureDAO" class="com.kog.fable.dao.PictureDAO">
<beans:property name="sessionFactory" ref="mySessionFactory" />
</beans:bean>
在这里,我不明白为什么,如果使用组件扫描,仍会显式声明DAO bean。由于DAO类带有注释,因此组件扫描功能不应该能够自行创建它们@Repository
吗?由于我认为此配置可能会创建重复的bean,因此我尝试删除xml条目,但随后开始获取:
org.springframework.beans.factory.BeanCreationException:创建名称为'addressController'的bean时出错:自动连接依赖项的注入失败;嵌套的异常是org.springframework.beans.factory.BeanCreationException:无法自动连线字段:私有com.kog.fable.dao.AddressDAO com.kog.fable.controller.AddressController.addressDAO; 嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建文件[*** \ com \ kog \ fable \ dao \ AddressDAO.class]中定义的名称为“ addressDAO”的bean时出错:调用init方法失败;嵌套异常是java.lang.IllegalArgumentException:需要'sessionFactory'或'hibernateTemplate'
在这里,我认为对我的DAO的HibernateDaoSupport扩展将使它们继承sessionFactory和相关方法,因此我不知道会发生什么。
我已经读过我可以将刷新模式设置为AUTO或将模板上的setCheckWriteOperations设置为FALSE来解决此类问题,并且看来可行,但是我想这无法确保所有情况下的事务一致性,因为我会喜欢它。
任何帮助将不胜感激,因为我是Spring和Hibernate的新手,并且在这里有些卡住。
扩展时,HibernateDaoSupport
您将无法从自动装配中受益,您将不得不覆盖该setSessionFactory
方法并在其上添加@Autowired
注释。否则它将无法正常工作。
我也希望<tx:annotation-driven />
没有它@Transactional
几乎是无用的,什么也不会做。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句