|
业务:通过spring管理数据源,实现用户注册。 错误分析:1.可能是sessionFactory的注入有问题 <?xml version="1.0" encoding="UTF-8"?> <!-- 定义数据源的信息 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/project" /> <property name="user" value="root" /> <property name="password" value="gg123" /> <property name="maxPoolSize"> <value>80</value> </property> <property name="minPoolSize"> <value>1</value> </property> <property name="initialPoolSize"> <value>1</value> </property> <property name="maxIdleTime"> <value>20</value> </property> </bean> <!--定义Hibernate的SessionFactory --> <!-- SessionFactory使用的数据源为上面的数据源 --> <!-- 指定了Hibernate的映射文件和配置信息 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref ="dataSource" /> <property name="mappingResources"> <list> <value>com/easi/beans/User.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="show_sql">true</prop> <prop key="hibernate.jdbc.batch_size">20</prop> </props> </property> </bean> <bean id="baseDao" class="com.easi.daoImpl.UserDao"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!--用户注册业务逻辑类 --> <bean id="userManager" class="com.easi.serviceImpl.UserManagerImpl"> <property name="dao"> <ref bean="baseDao" /> </property> </bean> <!-- 用户注册的Action --> <bean id="regAction" class="com.easi.action.RegisterAction"> <property name="userManager"> <ref bean="userManager" /> </property> </bean> //hibernateTemplate注入 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </beans> Registeraction.java 由struts拦截的action处理类 public class RegisterAction extends ActionSupport {
private static final long serialVersionUID = 1L;
//UserForm类是bean类,作用是接受前台的orm中的注册信息
private UserForm user;
public UserForm getUser() {
return user;
}
public void setUser(UserForm user) {
this.user = user;
}
private UserManager userManager;
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
public String execute() {
try {
userManager.regUser(user);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ERROR;
}
}
}
UserManagerImpl 业务实现类 public class UserManagerImpl implements UserManager {
private BaseDao dao;
public void setDao(BaseDao dao) {
this.dao = dao;
}
@Override
public void regUser(UserForm userForm) {
User user = new User();
//此方法将userForm中的值传给user
BeanUtils.copyProperties(userForm,user);
System.out.println("接受到的用户名:"+user.getUserName());
System.out.println("接受到的密码:"+user.getPassword());
System.out.println("接受到的性别:"+user.getGender());
dao.saveObject(user);
}
}
UserDao.java public class UserDao implements BaseDao {
//让spring自己注入
@Autowired
private HibernateTemplate hibernateTemplate;
@Override
public void saveObject(Object obj) throws HibernateException {
//想设置session的FlushMode但是报错Could not obtain transaction-synchronized Session for current thread
//Session session=hibernateTemplate.getSessionFactory().getCurrentSession();
//session.setFlushMode(FlushMode.ALWAYS);
//System.out.println("flush设置成功");
//这里报错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.
hibernateTemplate.save(obj);
System.out.println("运行到这里le ");
}
}
错误为dao层错误,其他层应该没有什么问题。查了很多Turn your Session into FlushMode.COMMIT/AUTO错误的解决方案,80%都说的OpenSessionInViewFilter配置问题,可是我根本没用OpenSessionInViewFilter!也没配置OurOpenSessionInViewFilter。求大神一定帮我解答!非常感谢! ps:国外网站也查了一些,有一个说加入下面的代码。但是加入到spring配置文件后,项目启动都不能。。不懂aop。。 <tx:advice id=”txAdvice”> |
|
![]() 40分 |
<tx:method name="*" propagation="REQUIRED" read-only="true"/> Hibernate4已经是全部用了自己的事务处理框架,Spring集成事务层必须打开事务放行。 |
![]() |
请问加上这段代码就行了么?在spring实物层(applicationContext2.xml)中添加就行? |
![]() |
尝试了一下配置事务
<!-- 事务 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" read-only="true"/> <tx:method name="create*" propagation="REQUIRED" read-only="false" /> <tx:method name="save*" propagation="REQUIRED" read-only="false" /> <tx:method name="reg*" propagation="REQUIRED" read-only="false" /> <tx:method name="update*" propagation="REQUIRED" read-only="false" /> <tx:method name="delete*" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice> <aop:config> <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(com.eai.serviceImpl.*.*(..))" order="1"/> </aop:config> 但是启动项目的时候报错,java.lang.IllegalStateException: BeanFactory not initialized or already closed – call “”refresh”” before accessing beans via the ApplicationContext。 |
![]() |
问题已经解决了。
问题就如异常所述,是flushmode属性问题。 对数据库的操作都属于事务的操作,而数据库默认是读已提交 read-only=”true”形式 当读写操作时会调用DAO方法,而操作DAO的核心业务是Service,即 Spring,然而Spring 要对调用DAO的方法加以控制,所以就产生了切面(advice) 新增配置如下: <bean id=”transactionManager” class=”org.springframework.orm.hibernate4.HibernateTransactionManager”> <property name=”sessionFactory” ref=”sessionFactory” /> </bean> <tx:advice id=”txAdvice” transaction-manager=”transactionManager”> <tx:attributes> <tx:method name=”*” propagation=”REQUIRED” read-only=”true”/> <tx:method name=”create*” propagation=”REQUIRED” read-only=”false” /> <tx:method name=”save*” propagation=”REQUIRED” read-only=”false” /> //实际只用到reg这个连接点。 <tx:method name=”reg*” propagation=”REQUIRED” read-only=”false” /> <tx:method name=”update*” propagation=”REQUIRED” read-only=”false” /> <tx:method name=”delete*” propagation=”REQUIRED” read-only=”false” /> </tx:attributes> </tx:advice> <aop:config> <aop:advisor id=”managerTx” advice-ref=”txAdvice” pointcut=”execution(* com.easi.serviceImpl.*.*(..)))” order=”1″/> </aop:config> 报错需要导入aop的一些包,根据错误提示缺什么导什么就行了。 虽然异常解决了,但是我觉得这种方式不好,其实根本原因就是readonly=fale所以不能写入数据源。只要单独设置数据源readonly属性即可,不需要引入切面。 当然引入切面好处是以后逻辑业务多了,spring可以可以通过切面连接点很好的保护数据源。 |

