java – “在只读模式下不允许写操作”错误:与Spring @Service @transaction @Repository和Hibernate混淆
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – “在只读模式下不允许写操作”错误:与Spring @Service @transaction @Repository和Hibernate混淆,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4894字,纯文字阅读大概需要7分钟。
内容图文
![java – “在只读模式下不允许写操作”错误:与Spring @Service @transaction @Repository和Hibernate混淆](/upload/InfoBanner/zyjiaocheng/787/1de43b9186bf46ed9abc06dd6b39a9b4.jpg)
我正在使用Spring和Hibernate处理一个现有的项目,并且因为我得到一个而感到困惑
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.
尝试保存对象时出错但我仍然无法找到究竟是什么错误.
有一个使用@Service注释的服务层和一个应该是事务性的保存方法,因此它使用@Transactional(readOnly = false)进行注释.对我来说,这意味着春天应该处理交易本身.
@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中,hibernate模板将获得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: Error
creating bean with name ‘addressController’: Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.kog.fable.dao.AddressDAO
com.kog.fable.controller.AddressController.addressDAO; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘addressDAO’ defined in file
[***\com\kog\fable\dao\AddressDAO.class]: Invocation of init method
failed; nested exception is java.lang.IllegalArgumentException:
‘sessionFactory’ or ‘hibernateTemplate’ is required
在这里,我认为HibernateDaoSupport对我的DAO的扩展会使它们继承sessionFactory和相关的方法,所以我不明白会发生什么.
我已经读过我可以将刷新模式设置为AUTO或将模板上的setCheckWriteOperations设置为FALSE以解决这类问题并且它似乎有效,但我想这不会确保所有情况下的事务一致性,因为我会喜欢它.
任何帮助都会受到赞赏,因为我对Spring和Hibernate很新,而且有点卡在这里.
解决方法:
扩展HibernateDaoSupport时,您不会受益于自动装配,您必须覆盖setSessionFactory方法并在其上放置@Autowired注释.否则它将无法工作.
我还希望< tx:annotation-driven />没有它,@ Transactal几乎没用,也没有做任何事情.
内容总结
以上是互联网集市为您收集整理的java – “在只读模式下不允许写操作”错误:与Spring @Service @transaction @Repository和Hibernate混淆全部内容,希望文章能够帮你解决java – “在只读模式下不允许写操作”错误:与Spring @Service @transaction @Repository和Hibernate混淆所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。