背景:我在DAO中使用Hibernate,它由业务层类使用。一切都在春天自动装配。我将sessionManager连接到DAO,然后将DAO连接到业务逻辑类。
我正在使用@Transactional进行基于注释的事务管理。
我看到的错误如下:
Could not create JDBC savepoint;
nested exception is
java.sql.SQLException: Connection is read-only.
Queries leading to data modification are not allowed.
抛出异常的方法是一个只读方法,按顺序包含两个只读读取。
我试图尽可能多地将代码提炼到这个演示中:
@Transactional(propagation = Propagation.REQUIRES_NEW,value="transactionManager",readOnly=true)
public Typ2 validateAndIfSoGet(String param){
Typ blah = dao1.getTyp(param);
if(blah!=null){
return dao2.getTyp2(blah);
}
else return null;
}
您可以看到在这一个事务中,有两个读取来自不同的DAO对象。为什么Spring抱怨保存点?读取之间必须有一些保存吗?那么正确的解决方法是使其成为readOnly = false吗?或者这是一个创可贴封面修复?
提前致谢。
编辑:
getTyp()
和getType2()
是DAO方法,它们调用相应的底层数据库以将行检索为对象。它们使用简单的Hibernate映射(1个DAO:1个表,1行:1个实体对象。)
完整的getTyp方法如下所示:
@Override
@Transactional(value="transactionManager",propagation = Propagation.NESTED,readOnly=true)
public Typ getTyp(String param){
Typ typ = (Typ) currentSession().get(Typ.class, param);
return typ;
}
(使用Hibernate的Session.get方法)。
getCurrentSession方法未注释。我不确定这是否与问题有关。
@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessFactory;
private Session currentSession(){
return sessFactory.getCurrentSession();
}
答案 0 :(得分:1)
这根本不是我所期待的。
在我的Hibernate配置中,我在
的SessionFactory中设置了一个属性<prop key="hibernate.current_session_context_class">thread</prop>
显然,这搞砸了Spring的交易管理。我删除了这个,突然我的所有基于Spring的事务管理工作。
这是一个帮助我的相关主题。 Spring Source Discussion Thread
感谢所有人帮助您排除故障。