Spring集成Hibernate5_01-basic
来源:互联网 发布:天音淘宝宝贝复制软件 编辑:程序博客网 时间:2024/06/02 06:50
1、导入hibernate的包和Spring的包
1.1、导入Spring的依赖包
1.2、导入Log4j的依赖包
1.3、导入dbcp的依赖包
1.4、导入Hibernate3的依赖包(hibernate3.jar,required文件中的所有,slf4j-api.jar,)
2、创建SpringBean.xml
2.1、使用DBCP创建dataSource, 和集成JDBC一样
设置jdbc.properties文件位置
<!-- 设置jdbc.properties文件位置 --> <context:property-placeholder location="jdbc.properties" />
2.2、创建Hibernate的的sessionFactory
2.2.1、首先我们看一下以前的hibernate.cfg.xml配置,创建sessionFactory
2.2.2、创建集成hibernate的sessionFactory
官网有介绍19.3.1 SessionFactory setup in a Spring container ,
下面为实际配置
3、为实体类创建hibernate的Annotation或者hbm文件
4、创建基于Hibernate的Dao
4.1、实现IUserDao
package com.chb.spring_hibernate.dao;import java.util.List;import com.chb.spring_hibernate.model.User;public class UserHibernateDao implements IUserDao{ ...//实现IUserDao的方法}
4.2、在相应的Dao中注入相应的SessionFactory
4.2.1、如果hibernate自己管理sessionFactory, 就要通过配置文件创建sessionFactory , 然后通过openSession来获取Session.
package com.chb.hbUtils;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class HibernateUtils { private static Session session; private static SessionFactory getFactory() { Configuration config = new Configuration().configure(); SessionFactory sessionFactory = config.buildSessionFactory(); return sessionFactory; } public static Session getSession() { if (session == null) { session = getFactory().openSession(); } return session; } public static void close() { if (session != null) { session.close(); } }}
4.2.2、如果通过Spring来管理相应的SessionFactory,不再使用factory.openSession()开启session,而应该是使用facotry.getCurrentSession来打开Session,这个Session就会被Spring所管理,此时开发人员不用进行事务控制,也不用关闭Session,全部有Spring容器来完成
/** * 获取Session, * 注意: 没有使用openSession(), 而是getCurrentSession()才能被Spring所管理 * @return */ private Session getSession() { return sessionFactory.getCurrentSession(); }
4.3、为Group创建基于Hibernate的Dao, 同样注入sessionFactory, 通过session来进行相应的操作。
package com.chb.spring_hibernate.dao;import javax.annotation.Resource;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.chb.spring_hibernate.model.Group;public class GroupHibernateDao implements IGroupDao{ //注入sessionFactory private SessionFactory sessionFactory; //提供相应的getter setter @Resource(name="mySessionFactory")//注入sessionFactory public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public SessionFactory getSessionFactory() { return sessionFactory; } /** * 获取Session, * 注意: 没有使用openSession(), 而是getCurrentSession()才能被Spring所管理 * @return */ private Session getSession() { return sessionFactory.getCurrentSession(); } public void addGroup(Group group) { }}
4.4、sessionFactory注入的优化
每多一个实体类, 我们都要注入SessionFactory, 这部分代码功能都是一样的, 我们如果每个Dao中重复写这部分代码就是做重复工作, 我们可以将这部分代码提取出来, 写一个BaseDao类
package com.chb.spring_hibernate.dao;import javax.annotation.Resource;import org.hibernate.Session;import org.hibernate.SessionFactory;public class BaseDao { //注入sessionFactory private SessionFactory sessionFactory; //提供相应的getter setter @Resource(name="mySessionFactory")//注入sessionFactory public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public SessionFactory getSessionFactory() { return sessionFactory; } /** * 获取Session, * 注意: 没有使用openSession(), 而是getCurrentSession()才能被Spring所管理 * @return * //使用protected权限,只有子类可以使用 */ protected Session getSession() { return sessionFactory.getCurrentSession(); }}
这样, GroupHibernateDao, UserHibernateDao 只需要继承BaseDao, 代码就简洁多了。
5、测试: 添加一哥group
package com.chb.spring_hibernate.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.chb.spring_hibernate.dao.GroupHibernateDao;import com.chb.spring_hibernate.dao.IGroupDao;import com.chb.spring_hibernate.model.Group;public class Test { @org.junit.Test public void testHibernateAdd(){ ApplicationContext context = new ClassPathXmlApplicationContext("SpringBean.xml"); IGroupDao groupDao = context.getBean(GroupHibernateDao.class); Group group = new Group(); group.setGroupName("计算机系"); groupDao.addGroup(group); }}
报错1、
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userHibernateDao': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mySessionFactory': Failed to introspect bean class [org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClassDefFoundError: [Lorg/hibernate/engine/FilterDefinition; at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.
原因: Spring整合Hibernate 使用注解类出错, 在Hibernate3可以使用AnnotationSessionFactoryBean来创建sessionFactory,但是,Hibernate4已经不支持这个了。
Hibernate 只能使用org.springframework.orm.hibernate4.LocalSessionFactoryBean
, 那么要怎么配置注解形式的model呢?很简单,因为LocalSessionFactoryBean里面已经整合了annotation,
public void setPackagesToScan(String... packagesToScan) { this.packagesToScan = packagesToScan; }
报错2、
原因: 配置Spring事务处理,只有配置了事务处理之后,Spring才能有效的管理事务
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
六、配置Spring事务处理,只有配置了事务处理之后,Spring才能有效的管理事务
参考: 20.4.3 Transaction management
Spring是通过aop来实现事务处理
再次执行测试, 继续报错3、java.lang.ClassCastException: com.sun.proxy.$Proxy20 cannot be cast to com.chb.spring_hibernate.dao.UserHibernateDao
java.lang.ClassCastException: com.sun.proxy.$Proxy20 cannot be cast to com.chb.spring_hibernate.dao.UserHibernateDao at com.chb.spring_hibernate.test.Test.testHibernateAdd(Test.java:22) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
解决参照: http://blog.csdn.net/danchaofan0534/article/details/53575106
继续报错4、java.lang.ClassNotFoundException: org.hibernate.engine.transaction.spi.TransactionContext
本项目是Spring4 + Hibernate5 , 但是在设置事务管理器时参考的是HIberrnate4的文档,导致出错。
报错6、java.lang.IllegalStateException: No value for key [org.hibernate.internal.SessionFactoryImpl@5226e402] bound to thread [main]
我他妈要疯了
java.lang.IllegalStateException: No value for key [org.hibernate.internal.SessionFactoryImpl@5226e402] bound to thread [main] at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:210) at org.springframework.orm.hibernate5.HibernateTransactionManager.doCleanupAfterCompletion(HibernateTransactionManager.java:649) at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1017) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:883) at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:830) at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:522) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:286) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy19.addGroup(Unknown Source) at com.chb.spring_hibernate.test.Test.testHibernateAdd(Test.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
碰巧和上面一样, 在注入sessionFactory时,
总算他妈的成功了,
测试load
GroupHibernateDao中load方法
public Group load(int id) { return getSession().load(Group.class, 1); }
测试
@org.junit.Test public void testLoad(){ ApplicationContext context = new ClassPathXmlApplicationContext("SpringBean.xml"); IGroupDao groupDao = (IGroupDao)context.getBean("groupHibernateDao"); System.out.println(groupDao.load(1)); }
测试结果: 报错7、org.hibernate.LazyInitializationException: could not initialize proxy - no Session
报错是一个懒加载异常,是在session(hibernate里的session)关闭后使用group对象的未加载变量,也就是说session已经关闭,然而该实例变量却还没有被初始化,就使用了该实例变量,导致该异常。
下面给出三种解决办法,个人认为第二种比较好
1、把lazy设成false。这个是最简单的办法,个人认为也是比较笨的方法。因为这是在用效率作为代价。
2、使用OpenSessionInViewFilter。这种方法是将session交给servlet filter来管理,每当一个请求来之后就会开
启一个session,只有当响应结束后才会关闭。如下:
3、将hibernate的抓起策略改为join。也就是是left join fetch或inner join fetch语法。就是在
我们会在后续中考虑OpenSessionInViewFilter, 本节先不处理, 将load改为get
阅读全文
0 0
- Spring集成Hibernate5_01-basic
- Spring Basic
- Spring Security Basic Authentication
- Spring集成
- spring spring mvc集成
- Spring MVC Basic Process Flow
- Spring Journey -- AOP basic concept
- Spring Boot集成Spring Data
- 【spring】spring 与 redis集成
- 【Spring】Struts和Spring集成
- Spring MVC + Spring + Hibernate集成
- spring boot 集成spring security
- spring boot 集成spring security
- 集成Spring和Axis
- JSF和Spring集成
- axis + spring 集成
- axis + spring 集成(2)
- JSF和Spring集成
- Atomic类和CAS
- 【gas-station】
- 旋转卡壳算法
- label元素浅析
- 项目实战
- Spring集成Hibernate5_01-basic
- ROS 学习
- mysql索引总结----mysql 索引类型以及创建
- 【开发笔记】JS中encodeURI与encodeURIComponent
- 求三维凸包重心到表面最短距离
- angular的缓存机制
- nodeJS入门——新建一个项目及代码详解
- 人脸检测——滑动窗口篇(训练和实现)
- Codeforces 842 D Vitya and Strange Lesson 线段树 (未理解透)