hibernate交spring事务托管后插入数据无效,不发送sql语句,不报错,但能查询到数据。
如果手动执行sessionFactory.getCurrentSession().flush()可以立即写入到数据库。
不手动的话无法自动事务提交。
怀疑是spring事务管理没起作用。
(学生党刚学框架,不妥当的地方还请明示)
dao层代码:
public class UserDao implements IUserDao{
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public boolean addUser(User user) {
LogUtil.getLog().info("正在执行user插入操作~");
try {
sessionFactory.getCurrentSession().save(user);
} catch (Exception e) {
LogUtil.getLog().error(e);
return false;
}
return true;
}
controller层:
if(code.equals(checkCode)){
if(userDao.addUser(user)){
//将用户信息加进session中
return "redirect:/returnIndex";
}else{
model.addAttribute("message", "系统异常,注册失败!");
return "forward:/user/returnRegiste";
}
}else{
model.addAttribute("message", "验证码错误!");
return "forward:/user/returnRegiste";
}
xml配置:
<!-- c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="user"><value>root</value></property>
<property name="password"><value></value></property>
<property name="minPoolSize"><value>20</value></property>
<property name="maxPoolSize"><value>100</value></property>
<property name="initialPoolSize"><value>20</value></property>
<property name="driverClass"><value>com.mysql.jdbc.Driver</value></property>
<property name="jdbcUrl"><value>jdbc:mysql://localhost:3306/db_shop?useUnicode=true&characterEncoding=UTF-8</value></property>
</bean>
<!-- session工厂 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="annotatedClasses">
<list>
<value>edu.hnuc.entity.User</value>
</list>
</property>
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">edu.hnuc.util.UTF8CharacterDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 通知 -->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!-- 切入点 -->
<aop:config>
<aop:pointcut expression="execution(* edu.hnuc.dao.impl.*.*(**))" id="myPoincut"/>
<aop:advisor advice-ref="myAdvice" pointcut-ref="myPoincut"/>
</aop:config>
<!-- openSessionInView -->
<mvc:interceptors>
<bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</mvc:interceptors>
文件结构:
PHPz2017-04-18 09:47:13
There is no transaction configured in your configuration file, how can it be automatically submitted? You can definitely only submit the transaction manually in the code
The simplest way is this
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Then add @Transactional on your dao method
Update the answer in the comment
Write like this
<aop:pointcut expression="execution(* edu.hnuc.dao.impl.*.*(..))" id="myPoincut"/>
ringa_lee2017-04-18 09:47:13
1. Since springMVC and hibernate are used, why not use spring’s hibernateTemplate?
2. You configure sessinFactory and transactionManager in your spring configuration file, but your DAO obtains the session from the sessionFactory itself, and there is no relevant transaction control code... I think it is because of this that the transaction is not submitted. It's like if you use a connection pool, but create a connection yourself using JDBCDriver, then the connection pool will definitely not be able to manage this Connection, because it doesn't even know there is such a connection...
Finally, I give you a suggestion: In the code during the debugging phase, it is better to add e.printStackTrace(), and it is best to add throw e, so that the upstream code knows that there is a problem in this layer. Otherwise, it may be due to human factors. (For example, forgetting to write "LogUtil.getLog().error(e);" or others) causes the exception message to be swallowed. If such an exception occurs, locating the problem will be very cumbersome.