hibernate4无法保存数据
author: hiu
以后都发文章我都备注一下作者了,hiu就是我了
红色字体更新日期:2014-07-08
初次使用hibernate4,使用getCurrentSession保存对象时无法将对象的数据保存进数据库,经过一番试验后,发现原来要配置事务才干保存数据。
保存数据失败原因:
没有配置事务,通过手动写一个事务,才干提交数据。手动写一个事务,用getCurrentSession也无法保存数据,仅仅能使用openSession才干保存数据。
解决的方法:
配置spring声明式事务,不建议使用注解来配置事务,注解配置事务,仅仅在xml配置切面事务失败时,才用来測试。一般xml配置切面事务失败原因,找不到包,还有切面路径找不到类。今天(2014-07-08)在保存数据时发现,假设做一对多的表保存数据的话,即使xml配置切面事务的切面不对,也能使用getCurrentSession保存数据,但事务就无法回滚了:
spring-hibernate.xml
<aop:config>
<!--我在Service前面加了1234,目的:不让匹配到相应的类开启事务-->
<aop:pointcut />
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>
service层代码:
public EmployeeVo save(EmployeeVo employeeVo, Map<String, String> pageParam) throws SQLException {
Employee employee =new Employee();
String keyjobno=employeeVo.getCompany().trim()+employeeVo.getJobno().trim();
//employee表
employeeVo.setKeyjobno(keyjobno.trim());//主键,公司+工号
employeeVo.setIfout("在会");
BeanUtils.copyProperties(employeeVo, employee);
//in_union_his表
InUnionHis inunion=new InUnionHis();
BeanUtils.copyProperties(employeeVo, inunion);
inunion.setEmployee(employee);
Set<InUnionHis> inUnionHises = new HashSet<InUnionHis>();
inUnionHises.add(inunion);
employee.setInUnionHises(inUnionHises);
employeeDao.save(employee);
return employeeVo;
}
以上是用来做插入的,在保存主表employee表(一方)数据时,也将从表in_union_his(多方)的数据保存,控制台打印出来的sql语句:
2014-07-08 18:33:46 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.employee
(bornboon, borndate, company, createdate, dept, getborndate, getmarrydate, id, identitycard, ifout, interest, jobno, lodging, marry, marryboon, name, nativename, operator, phone, politicsface, sex, keyjobno)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.employee
(bornboon, borndate, company, createdate, dept, getborndate, getmarrydate, id, identitycard, ifout, interest, jobno, lodging, marry, marryboon, name, nativename, operator, phone, politicsface, sex, keyjobno)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2014-07-08 18:33:46 [org.hibernate.engine.spi.ActionQueue]-[DEBUG] Executing identity-insert immediately
2014-07-08 18:33:46 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.in_union_his
(createdate, keyjobno, inuniondate, operator)
values
(?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.in_union_his
(createdate, keyjobno, inuniondate, operator)
values
(?, ?, ?, ?)
2014-07-08 18:33:46 [org.hibernate.id.IdentifierGeneratorHelper]-[DEBUG] Natively generated identity: 81
2014-07-08 18:33:46 [org.springframework.security.web.context.HttpSessionSecurityContextRepository]-[DEB
能够看到sql语句插入了两张表的数据,这就说明了在没有配置相应的事务切面时,依旧能够使用getCurrentSession保存数据,只是这样的前提是一定要在一对多的表关系中进行才干够的,假设我将上面service层//in_union_his表以下的代码去掉,仅仅做保存employee表,这时使用
getCurrentSession保存数据是无法运行的,在控制台也没有不论什么的sql语句打印出来的。
说明 :
1、要注意,在web.xml配置openSessionInViewFilter用来启动hibernate,在经过url请求后,这里就会开启hibernate的session,假设不配置,就无法使用getCurrentSession了,具体配置,请看以下web.xml的配置,
2、以下的代码是用AOP配置的事务,注解方式的事务我已经凝视掉了,请看UserService里面凝视掉的事务注解
3、dao和service我都是用注解注入的
4、以下的几个xml文件除了applicationContext-security.xml这个配置文件外,其他的几个xml文件都是參照easyUI教程中的孙宇老师的视频配置的,有兴趣的朋友可下载下来看看,比較适合刚入门的朋友
5、项目是用maven搭建的,比較方便的,不用再去找jar包,仅仅要在pom.xml文件配置,在连接网络的前提下就能够自己主动下载jar包了,能够看看以下的pom.xml文件里,我下载了那些jar包
6、由于我在spring-hibernate.xml文件配置了<prop key="hibernate.show_sql">${hibernate.show_sql}</prop> ,这个值为true时,假设运行了sql语句,就会在控制台打印出sql语句的,我在測试时,假设数据没保存进数据库,控制台是不会打印出sql语句的,成功保存数据后,打印出的信息:
2014-06-28 16:40:10 [org.hibernate.SQL]-[DEBUG]
insert
into
union_ssh.pub_users
(enabled, issys, user_account, user_desc, user_name, user_password, user_id)
values
(?, ?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
union_ssh.pub_users
(enabled, issys, user_account, user_desc, user_name, user_password, user_id)
values
(?, ?, ?, ?, ?, ?, ?)
以下贴出代码:
UserService:
package com.user.service;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.user.dao.UserDaoI;
import com.user.model.PubUsers;
import com.user.pageModel.UsersPageModel;
import framework.base.dao.BaseDaoI;
import framework.base.model.DataGrid;
import framework.base.model.GridModel;
import framework.base.model.User;
@Service("userService")
@Transactional 使用注解配置事务
public class UserService {
private UserDaoI userDaoi;
//以下3个注解都是用来配置事务的,仅仅要在这个类的头部加上事务注解,就能保存数据进数据库,不管使用那个,都不会影响数据是提交
/*
* 假设有事务, 那么增加事务, 没有的话新建一个(默认情况下)
* @Transactional(propagation=Propagation.REQUIRED)
*/
/*不管是否存在事务,都创建一个新的事务,原来的挂起,新的运行完成,继续运行老的事务
* @Transactional(propagation=Propagation.REQUIRES_NEW)
*/
/*容器不为这种方法开启事务
* @Transactional(propagation=Propagation.NOT_SUPPORTED)
*/
public User save(User user) throws Exception {
PubUsers t = new PubUsers();
BeanUtils.copyProperties(user, t);
t.setUserId(88);
t.setEnabled(1);
t.setIssys(1);
userDaoi.save(t);
//throw new RuntimeException();//用来測试事务回滚
return user;
}
public BaseDaoI<PubUsers> getUserDao() {
return userDao;
}
public UserDaoI getUserDaoi() {
return userDaoi;
}
@Autowired
public void setUserDaoi(UserDaoI userDaoi) {
this.userDaoi = userDaoi;
}
}
UserDaoI:
package com.user.dao;
import java.util.List;
import com.user.model.PubUsers;
public interface UserDaoI {
public void save(PubUsers t);
}
UserDaoImpl:
package com.user.dao.impl;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.user.dao.UserDaoI;
import com.user.model.PubUsers;
@Repository(value="userDao")
public class UserDaoImpl implements UserDaoI {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* 获得当前事物的session
*
* @return org.hibernate.Session
*/
public Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
//配置事务后,直接使用这里,就可保存数据进数据库了
@Override
public void save(PubUsers t) {
Session session=this.sessionFactory.getCurrentSession();
session.save(t);
}
//这种方法是在没有配置spring事务时使用的測试,这里我已经測试过了,在UserDaoI中已经删除了这个接口
public void saveTest(PubUsers t){
//方法1,不能成功
/* Session session=this.sessionFactory.getCurrentSession();
session.save(t); */
//2,不成功
/* Session session=this.sessionFactory.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(t);
tx.commit();//这里一提交,数据就保存进数据库了
*/
//方法3,不成功
/* Session session=this.sessionFactory.openSession();
session.save(t); */
//方法4,事务提交后,成功保存数据到数据库
Session session=this.sessionFactory.openSession();
Transaction tx=session.beginTransaction();
session.save(t);
tx.commit();//这里一提交,数据就保存进数据库了
}
}
spring-hibernate.xml,主要配置了数据库连接,和事务:
spring.xml
web.xml
applicationContext-security.xml,这个本来不打算贴出来的,由于这是spring security权限管理的配置文件,仅仅供大家參考一下,以后有时间,再发一下这个配置的文章
pom.xml<!--注解事务要引入的包--> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project>也贴上一张项目的架构图吧