首页 > 代码库 > hibernate4无法保存数据

hibernate4无法保存数据

hibernate4无法保存数据

author: hiu

以后都发文章我都备注一下作者了,hiu就是我了大笑


初次使用hibernate4,使用getCurrentSession保存对象时无法将对象的数据保存进数据库,经过一番试验后,发现原来要配置事务才能保存数据。

保存数据失败原因:

没有配置事务,通过手动写一个事务,才能提交数据。手动写一个事务,用getCurrentSession也无法保存数据,只能使用openSession才能保存数据。

解决办法:

配置spring声明式事务,不建议使用注解来配置事务,注解配置事务,只在xml配置切面事务失败时,才用来测试。一般xml配置切面事务失败原因,找不到包,还有切面路径找不到类


说明 :

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=http://www.mamicode.com/"userDao")>


spring-hibernate.xml,主要配置了数据库连接,和事务:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
">

	<!-- JNDI方式配置数据源 -->
	<!-- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value=http://www.mamicode.com/"${jndiName}">  -->>
spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">

	<!-- 引入属性文件
	<bean id="propertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	   <property name="location">
		  <value>classpath:jdbc.properties</value>
	   </property>
	</bean>
	 -->
	<context:property-placeholder location="classpath:config.properties" />

	<!-- 自动扫描包 ,主要为了使用注解注入,如果不扫描,就无法使用注解注入了,不过这里扫不扫描和事务配置无关-->
	<context:component-scan base-package="com.*.dao.impl,com.*.service,framework.base.dao.impl"/>

</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name></display-name>
  
  <!-- spring配置文件位置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring.xml,classpath:spring-hibernate.xml,classpath:applicationContext-security.xml</param-value>
	</context-param> 
	
   <!-- spring security 过滤器, 这个的位置顺序和spring的监听器启动位置没有什么关系,可以放在spring监听器的前面,也可以放置在后面。
    但一定要放在struts的过滤器前面,因为如果有自定义的登录页面,当登录时,就会跳转到了struts对应的action中,
    导致无法使用spring security的验证登录了,正常情况下,应该登录时,会经过自定义的MyUsernamePasswordAuthenticationFilter类的attemptAuthentication方法进行验证。
  如果验证成功,则登录成功,不再执行对应的action验证登录 ;spring security验证失败,则跳回指定登录失败的页面。  
   -->
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>	  

   <!-- spring监听器 -->
   <listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>	

  <!-- hibernate配置 -->
	<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    <init-param>
      <param-name>singleSession</param-name>
      <param-value>true</param-value>
      </init-param>
    </filter>

  <!-- Struts2配置 -->
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<!-- hibernate的session启动过滤器,在url请求action时启动 ,不配置这个,url请求时无法启动hibernate的session-->
	 <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
	  <!-- struts拦截的url后缀 -->
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.action</url-pattern>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
     
    <!-- 修复数据库监听器
	<listener>
		<listener-class>com.menu.listener.RepairListener</listener-class>
	</listener>
 -->
 
  <!-- 登录验证码的servlet -->
  <servlet>
    <servlet-name>CheckCode</servlet-name>
    <servlet-class>framework.util.CheckCode</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>CheckCode</servlet-name>
    <url-pattern>/servlet/CheckCode</url-pattern>
  </servlet-mapping>
 
   
   <!-- log4j ,用来启动log4j  -->
   <servlet>
    <servlet-name>Log4jInitServlet</servlet-name>
    <servlet-class>
        framework.util.Log4jInitServlet
   </servlet-class>
   <init-param>
      <param-name>log4jLocation</param-name>
      <param-value>WEB-INF/classes/log4j.properties</param-value>
   </init-param>
   <load-on-startup>0</load-on-startup>
</servlet>
  
  
  <welcome-file-list>
    <welcome-file>/login.jsp</welcome-file>
  </welcome-file-list>
</web-app>


applicationContext-security.xml,这个本来不打算贴出来的,因为这是spring security权限管理的配置文件,只供大家参考一下,以后有时间,再发一下这个配置的文章

<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security.xsd">
     
    <!--  No bean named 'springSecurityFilterChain' is defined   
    1、 这时发布一下你的项目,查看tomcat的webapps目录下,找到你的项目文件夹的classes文件夹有没有相关的spring.xml文件存在,不存在就会报错
    2、查看web.xml文件<param-value>标签有没有引入applicationContext-security.xml这个文件
        -->
     
      <!-- 不用经过spring security过滤,一般js、css都不需要过滤   -->
     
      <http pattern="/*/js/**" security="none"/> 
      <http pattern="/common/js/**" security="none"/>
      <http pattern="/login.jsp" security="none"/> 
      
      <!-- auto-config="true" -->  
      <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint" >
	     <!-- 不再在这里对url进行权限拦截,在数据库中取出url中对应的权限  
	       <intercept-url pattern="/**" access="ROLE_USER" />
	     -->
           <!-- 单用户登陆 -->
           <session-management>
              <concurrency-control max-sessions="1"
                error-if-maximum-exceeded="true" />
           </session-management>
      
 <!-- 这种自定义的登录页面,不能经过security的用户信息验证,也就等于不能取出用户的权限     
           <form-login login-page='/login.jsp' default-target-url="/index.jsp"/>
  -->          
            <!-- 尝试访问没有权限的页面时跳转的页面 -->      
           <access-denied-handler error-page="/403.jsp"/>
          
           <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER"  />   
             
           <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
   
           <!-- 检测失效的sessionId,session超时时,定位到另外一个URL -->  
            <session-management invalid-session-url="/sessionTimeOut.jsp" /> 
        <!-- 
            <custom-filter ref="logoutFilter" before="LOGOUT_FILTER"/>
             -->
             
             <logout invalidate-session="true"  logout-success-url="/"  logout-url="/logout"/>
	  </http>

         <!-- 登录验证器 -->  
    <beans:bean id="loginFilter"  
        class="framework.security.login.MyUsernamePasswordAuthenticationFilter">  
       
        <!-- value=http://www.mamicode.com/"/loginUser.action"处理登录表单的action ,value值要以“/”开关,否则会报错 :>
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>SSHMS</groupId>
  <artifactId>SSHMS</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name/>
  <description/>
  
  <!-- 指定Maven仓库 -->
	<repositories>
		<repository>
			<id>maven</id>
			<name>Maven Repository Switchboard</name>
			<layout>default</layout>
			<url>http://repo1.maven.org/maven2</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>alibaba-opensource</id>
			<name>alibaba-opensource</name>
			<url>http://code.alibabatech.com/mvn/releases/</url>
			<layout>default</layout>
		</repository>
		<repository>
			<id>alibaba-opensource-snapshot</id>
			<name>alibaba-opensource-snapshot</name>
			<url>http://code.alibabatech.com/mvn/snapshots/</url>
			<layout>default</layout>
		</repository>
	</repositories>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  
  <dependencies>

  <!-- servlet -->
    <dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>servlet-api</artifactId>
		<version>2.5</version>
		<scope>provided</scope>
    </dependency>
    
  <!-- JUnit4 -->
     <dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11-beta-1</version>
			<scope>test</scope>
	 </dependency>
  
   <!-- log4j -->
	<dependency>
		<groupId>log4j</groupId>
		<artifactId>log4j</artifactId>
		<version>1.2.17</version>	
	</dependency>
	
	<!-- fastJson -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>1.1.24</version>
	</dependency>
	
	<!-- spring3 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>
   
   
     <!-- struts2 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.16.3</version>
			<!-- 如果有hibernate时要去除这个,因为hibernate也有这个类,不能以这个代替hibernate的那个,否则会出错 --> 
			<exclusions>
				<exclusion>
					<groupId>javassist</groupId>
					<artifactId>javassist</artifactId>
				</exclusion>
			</exclusions>
			
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>2.3.16.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-convention-plugin</artifactId>
			<version>2.3.16.3</version>
		</dependency>
  
  
      <!-- 加入mysql驱动依赖包 -->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.27</version>
	</dependency>
	
  <!-- 加入druid数据源依赖包 -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
		<version>1.0.0</version>
	</dependency>
	
	<!-- spring事务切面的包 -->
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjweaver</artifactId>
		<version>1.7.4</version>
	</dependency>
	 
	<!-- hibernate4 -->
	   <dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>4.1.7.Final</version>
	   </dependency>
		
	 <!-- spring security  -->
   <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>3.2.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>3.2.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>3.2.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
      
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.2.8.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  
    <!-- 
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/web/context/request/async/CallableProcessingInterceptor
     -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>3.2.8.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>	

    <!--注解事务要引入的包-->
    <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>

也贴上一张项目的架构图吧