> hibernate4 和 spring3 整合注意事项:HibernateDaoSupport没有了找到篇好文章,我之前遇到的问题都在这都能找到。其实出现这些问题的关键就是hibernate4和hib
hibernate4 和 spring3 整合注意事项:HibernateDaoSupport没有了找到篇好文章,我之前遇到的问题都在这都能找到。其实出现这些问题的关键就是hibernate4和hib
Hibernate4的改动较大只有spring3.1以上版本能够支持,Spring3.1取消了HibernateTemplate,因为Hibernate4的事务管理已经很好了,不用Spring再扩展了。这里简单介绍了hibernate4相对于hibernate3配置时出现的错误,只列举了问题和解决方法,详细原理如果大家感兴趣还是去自己搜吧,网上很多。Spring3.1去掉了HibernateDaoSupport类。hibernate4需要通过getCurrentSession()获取session。并且设置&prop key=&hibernate.current_session_context_class&&org.springframework.orm.hibernate4.SpringSessionContext&/prop&(在hibernate3的时候是thread和jta)。缓存设置改为&prop key=&hibernate.cache.provider_class&&net.sf.ehcache.hibernate.EhCacheProvider&/prop&&prop key=&hibernate.cache.region.factory_class&&org.hibernate.cache.ehcache.EhCacheRegionFactory&/prop&Spring对hibernate的事务管理,不论是注解方式还是配置文件方式统一改为:&bean id=&txManager& class=&org.springframework.orm.hibernate4.HibernateTransactionManager& &&property name=&sessionFactory&&&ref bean=&sessionFactory&/&&/property& &/bean&getCurrentSession()事务会自动关闭,所以在有所jsp页面查询数据都会关闭session。要想在jsp查询数据库需要加入:org.springframework.orm.hibernate4.support.OpenSessionInViewFilter过滤器。Hibernate分页出现 ResultSet may only be accessed in a forward direction 需要设置hibernate结果集滚动 &prop key=&jdbc.use_scrollable_resultset&&false&/prop&找到篇好文章,我之前遇到的问题都在这都能找到。其实出现这些问题的关键就是hibernate4和hibernate3出现了session管理的变动。spring也作出相应的变动....错误1:java.lang.NoClassDefFoundError: org/hibernate/cache/CacheProvider原因:spring的sessionfactory和transactionmanager与支持hibernate3时不同。解决: &bean id=&sessionFactory& class=&org.springframework.orm.hibernate4.LocalSessionFactoryBean&&&property name=&dataSource& ref=&dataSource&/&...&/bean&&bean id=&transactionManager& class=&org.springframework.orm.hibernate4.HibernateTransactionManager&&&property name=&sessionFactory& ref=&sessionFactory&/&&/bean&错误2:java.lang.NoSuchMethodError:org.hibernate.SessionFactory.openSession()Lorg/hibernate/classic/Session原因:hibernate4之后,spring31把HibernateDaoSupport去除,包括数据访问都不需要hibernatetemplate,这意味着dao需要改写,直接使用hibernate的session和query接口。解决:为了改写dao,足足花了一天时间,然后一个个接口进行单元测试,这是蛋疼的一个主要原因。错误3:nested exception is org.hibernate.HibernateException: No Session found for current thread原因:发现一些bean无法获得当前session,需要把之前一些方法的事务从NOT_SUPPORT提升到required,readonly=true见https://jira.springsource.org/browse/SPR-9020, /topic/1120924解决: &tx:advice id=&baseServiceAdvice& transaction-manager=&transactionManager&&&tx:attributes&&tx:method name=&get*& read-only=&true& propagation=&REQUIRED&/&&!--之前是NOT_SUPPORT--&&tx:method name=&find*& read-only=&true& propagation=&REQUIRED&/&&!--之前是NOT_SUPPORT--&&tx:method name=&save*& propagation=&REQUIRED&/&&tx:method name=&update*& propagation=&REQUIRED&/&&tx:method name=&remove*& propagation=&REQUIRED&/&&tx:method name=&add*& propagation=&REQUIRED&/&&!--默认其他方法都是REQUIRED--&&tx:method name=&*&/&&/tx:attributes&&/tx:advice&错误4:与错误3报错类似,java.lang.NoSuchMethodError:org.hibernate.SessionFactory.openSession()Lorg/hibernate/classic/Sat org.springframework.orm.hibernate3.SessionFactoryUtils.doGetSession(SessionFactoryUtils.java:324) [spring-orm-3.1.1.RELEASE.jar:3.1.1.RELEASE]at org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(SessionFactoryUtils.java:202) [spring-orm-3.1.1.RELEASE.jar:3.1.1.RELEASE]at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter原因:因为opensessioninview filter的问题,如果你的配置还是hibernate3,需要改为hibernate4 &filter&&filter-name&openSessionInViewFilter&/filter-name&&filter-class&org.springframework.orm.hibernate4.support.OpenSessionInViewFilter&/filter-class&&/filter&--------------------------------------------------------------------由于Hibernate4已经完全可以实现事务了, 与Spring3.1中的hibernatedao,hibernateTemplete等有冲突,所以Spring3.1里已经不提供Hibernatedaosupport,HibernateTemplete了,只能用Hibernate原始的方式用session:Session session = sessionFactory.openSession();Session session = sessionFactory.getCurrentSession();在basedao里可以用注入的sessionFactory获取session.注意, 配置事务的时候必须将父类baseServiceImpl也配上,要不然会出现错误:No Session found for currentthread, 以前是不需要的SessionFactory.getCurrentSession()的后台实现是可拔插的。因此,引入了新的扩展接口 (org.hibernate.context.spi.CurrentSessionContext)和新的配置参数(hibernate.current_session_context_class),以便对什么是“当前session”的范围和上下文(scope and context)的定义进行拔插。在Spring @Transactional声明式事务管理,”currentSession”的定义为: 当前被 Spring事务管理器 管理的Session,此时应配置:hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext。此处一定注意 使用 hibernate4,在不使用OpenSessionInView模式时,在使用getCurrentSession()时会有如下问题: 当有一个方法list 传播行为为Supports,当在另一个方法getPage()(无事务)调用list方法时会抛出 org.hibernate.HibernateException: No Session found for current thread 异常。 这是因为getCurrentSession()在没有session的情况下不会自动创建一个,不知道这是不是Spring3.1实现的 bug。 因此最好的解决方案是使用REQUIRED的传播行为。 总之:spring对hibernate的session长度的管理于是事物关系在一起,当事物结束的时候session关闭,当事物中断或异常的时候session关闭,此种方式比在容器初始化的时(&filter&&filter-name&openSessionInViewFilter&/filter-name&&filter-class&org.springframework.orm.hibernate4.support.OpenSessionInViewFilter&/filter-class&&/filter&)候打开session性能要好,
Hibernate4的改动较大只有spring3.1以上版本能够支持,Spring3.1取消了HibernateTemplate,因为Hibernate4的事务管理已经很好了,不用Spring再扩展了。这里简单介绍了hibernate4相对于hibernate...
------分隔线----------------------------
相关阅读排行
相关最新文章
Copyright 2012- ( Coin163 ) All Rights Reserved &&当前位置: >
spring学习笔记 用Hibernate实现UserDAO
发布时间: 01:41 类别:
要实现Hibernate UserDAO,需要完成以下几步:
1. 在目录src/org/appfuse/dao/hibernate下创建一个文件UserDAOHibernate.java,
这个类继承了HibernateDaoSupport类,并实现了UserDAO接口。
packageorg.appfuse.dao.
//useyourIDEtohandleimports
public class UserDAOHibernate extends HibernateDaoSupport implementsUserDAO{
private Loglog=LogFactory.getLog(UserDAOHibernate.class);
public List getUsers(){
return getHibernateTemplate().find(&fromUser&);
public User getUser(Long id){
return(User)getHibernateTemplate().get(User.class,id);
public void saveUser(User user){
getHibernateTemplate().saveOrUpdate(user);
if(log.isDebugEnabled()){
log.debug(&userIdsetto:&+user.getId());
public void removeUser(Longid){
Object user=getHibernateTemplate().load(User.class,id);
getHibernateTemplate().delete(user);
Spring的HibernateDaoSupport类是一个方便实现Hibernate DAO的超类,你可以利用其一
些有用的方法,来获得Hibernate &DAO或是SessionFactory。最方便的方法是
getHibernateTemplate(),它返回一个HibernateTempalte对象。这个模板把检测式
异常(checked &exception)包装成运行时式异常(runtime &exception),这使得你的DAO接口无需抛
出Hibernate异常。
程序还没有把UserDAO绑定到UserDAOHibernate上,必须创建它们之间的关联。
2. 在Spring配置文件(web/WEB-INF/ApplicationContext.xml)中添加以下内容:
&beanid=&userDAO&class=&org.appfuse.dao.hibernate.UserDAOHibernate&&
&propertyname=&sessionFactory&&
&reflocal=&sessionFactory&/&
&/property&
这样就在你的UserDAOHibernate(从HibernateDaoSupport的setSessionFactory继
承)中建了一个HibernateSessionFactory。Spring会检测一个Session(也就是,它在
web层是开放的)是否已经存在,并且直接使用它,而不是新建一个。这样你可以使用Spring流
行的&Open Session in View&模式来延迟载入collections。
下一篇: 上一篇:
猜你会喜欢....
声明:本站所有文章除标明原创外,均来自网络转载,版权归原作者所有,如果有侵犯到您的权益,请联系本站删除 网站管理员:SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结 - 开涛的博客(扫一扫头像关注公众号,掌握最新技术&架构) - ITeye技术网站
博客分类:
一 开发环境
1、动态web工程
2、部分依赖
java代码:
hibernate-release-4.1.0.Final.zip
hibernate-validator-4.2.0.Final.jar
spring-framework-3.1.1.RELEASE-with-docs.zip
proxool-0.9.1.jar
log4j 1.2.16
slf4j -1.6.1
mysql-connector-java-5.1.10.jar
hamcrest 1.3.0RC2
ehcache 2.4.3
3、为了方便学习,暂没有使用maven构建工程
二 工程主要包括内容
1、springMVC + spring3.1.1 + hibernate4.1.0集成
2、通用DAO层 和 Service层
3、二级缓存 Ehcache
4、REST风格的表现层
5、通用分页(两个版本)
5.1、首页 上一页,下一页 尾页 跳转
5.2、上一页 1 2 3 4 5 下一页
6、数据库连接池采用proxool
7、spring集成测试
8、表现层的 java validator框架验证(采用hibernate-validator-4.2.0实现)
9、视图采用JSP,并进行组件化分离
三 TODO LIST
将本项目做成脚手架方便以后新项目查询
1、Service层进行AOP缓存(缓存使用Memcached实现)
2、单元测试(把常见的桩测试、伪实现、模拟对象演示一遍 区别集成测试)
3、监控功能
后台查询hibernate二级缓存 hit/miss率功能
后台查询当前服务器状态功能(如 线程信息、服务器相关信息)
4、spring RPC功能
5、spring集成 quartz 进行任务调度
6、spring集成 java mail进行邮件发送
7、DAO层将各种常用框架集成进来(方便查询)
8、把工作中经常用的东西 融合进去,作为脚手架,方便以后查询
四 集成重点及常见问题
1、spring-config.xml 配置文件:
1.1、该配置文件只加载除表现层之外的所有bean,因此需要如下配置:
java代码:
&context:component-scan base-package="cn.javass"&
&context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/&
&/context:component-scan&
通过exclude-filter 把所有 @Controller注解的表现层控制器组件排除
1.2、国际化消息文件配置
java代码:
&!-- 国际化的消息资源文件 --&
&bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&
&property name="basenames"&
&!-- 在web环境中一定要定位到classpath 否则默认到当前web应用下找
&value&classpath:messages&/value&
&/property&
&property name="defaultEncoding" value="UTF-8"/&
&property name="cacheSeconds" value="60"/&
此处basenames内一定是 classpath:messages ,如果你写出“messages”,将会到你的web应用的根下找 即你的messages.properties一定在 web应用/messages.propertis。
1.3、hibernate的sessionFactory配置 需要使用org.springframework.orm.hibernate4.LocalSessionFactoryBean,其他都是类似的,具体看源代码。
1.4、&aop:aspectj-autoproxy expose-proxy="true"/& 实现@AspectJ注解的,默认使用AnnotationAwareAspectJAutoProxyCreator进行AOP代理,它是BeanPostProcessor的子类,在容器启动时Bean初始化开始和结束时调用进行AOP代理的创建,因此只对当容器启动时有效,使用时注意此处。
1.5、声明式容器管理事务
建议使用声明式容器管理事务,而不建议使用注解容器管理事务(虽然简单),但太分布式了,采用声明式容器管理事务一般只对service层进行处理。
java代码:
&tx:advice id="txAdvice" transaction-manager="txManager"&
&tx:attributes&
&tx:method name="save*" propagation="REQUIRED" /&
&tx:method name="add*" propagation="REQUIRED" /&
&tx:method name="create*" propagation="REQUIRED" /&
&tx:method name="insert*" propagation="REQUIRED" /&
&tx:method name="update*" propagation="REQUIRED" /&
&tx:method name="merge*" propagation="REQUIRED" /&
&tx:method name="del*" propagation="REQUIRED" /&
&tx:method name="remove*" propagation="REQUIRED" /&
&tx:method name="put*" propagation="REQUIRED" /&
&tx:method name="use*" propagation="REQUIRED"/&
&!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到--&
&tx:method name="get*" propagation="REQUIRED" read-only="true" /&
&tx:method name="count*" propagation="REQUIRED" read-only="true" /&
&tx:method name="find*" propagation="REQUIRED" read-only="true" /&
&tx:method name="list*" propagation="REQUIRED" read-only="true" /&
&tx:method name="*" read-only="true" /&
&/tx:attributes&
&/tx:advice&
&aop:config expose-proxy="true"&
&!-- 只对业务逻辑层实施事务 --&
&aop:pointcut id="txPointcut" expression="execution(* cn.javass..service..*.*(..))" /&
&aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/&
&/aop:config&
此处一定注意 使用 hibernate4,在不使用OpenSessionInView模式时,在使用getCurrentSession()时会有如下问题:
当有一个方法list 传播行为为Supports,当在另一个方法getPage()(无事务)调用list方法时会抛出org.hibernate.HibernateException: No Session found for current thread 异常。
这是因为getCurrentSession()在没有session的情况下不会自动创建一个,不知道这是不是Spring3.1实现的bug,欢迎大家讨论下。
因此最好的解决方案是使用REQUIRED的传播行为。
二、spring-servlet.xml:
2.1、表现层配置文件,只应加装表现层Bean,否则可能引起问题。
java代码:
&!-- 开启controller注解支持 --&
&!-- 注:如果base-package=cn.javass 则注解事务不起作用--&
&context:component-scan base-package="cn.javass.demo.web.controller"&
&context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/&
&/context:component-scan&
此处只应该加载表现层组件,如果此处还加载dao层或service层的bean会将之前容器加载的替换掉,而且此处不会进行AOP织入,所以会造成AOP失效问题(如事务不起作用),再回头看我们的1.4讨论的。
2.2、&mvc:view-controller path="/" view-name="forward:/index"/& 表示当访问主页时自动转发到index控制器。
2.3、静态资源映射
java代码:
&!-- 当在web.xml 中
DispatcherServlet使用
&url-pattern&/&/url-pattern& 映射时,能映射静态资源 --&
&mvc:default-servlet-handler/&
&!-- 静态资源映射 --&
&mvc:resources mapping="/images/**" location="/WEB-INF/images/" /&
&mvc:resources mapping="/css/**" location="/WEB-INF/css/" /&
&mvc:resources mapping="/js/**" location="/WEB-INF/js/" /&
以上是配置文件部分,接下来来看具体代码。
三、通用DAO层Hibernate4实现
为了减少各模块实现的代码量,实际工作时都会有通用DAO层实现,以下是部分核心代码:
java代码:
public abstract class BaseHibernateDao&M extends java.io.Serializable, PK extends java.io.Serializable& implements IBaseDao&M, PK& {
protected static final Logger LOGGER = LoggerFactory.getLogger(BaseHibernateDao.class);
private final Class&M& entityC
private final String HQL_LIST_ALL;
private final String HQL_COUNT_ALL;
private final String HQL_OPTIMIZE_PRE_LIST_ALL;
private final String HQL_OPTIMIZE_NEXT_LIST_ALL;
private String pkName =
@SuppressWarnings("unchecked")
public BaseHibernateDao() {
this.entityClass = (Class&M&) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Field[] fields = this.entityClass.getDeclaredFields();
for(Field f : fields) {
if(f.isAnnotationPresent(Id.class)) {
this.pkName = f.getName();
Assert.notNull(pkName);
//TODO @Entity name not null
HQL_LIST_ALL = "from " + this.entityClass.getSimpleName() + " order by " + pkName + " desc";
HQL_OPTIMIZE_PRE_LIST_ALL = "from " + this.entityClass.getSimpleName() + " where " + pkName + " & ? order by " + pkName + " asc";
HQL_OPTIMIZE_NEXT_LIST_ALL = "from " + this.entityClass.getSimpleName() + " where " + pkName + " & ? order by " + pkName + " desc";
HQL_COUNT_ALL = " select count(*) from " + this.entityClass.getSimpleName();
@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessionF
public Session getSession() {
//事务必须是开启的,否则获取不到
return sessionFactory.getCurrentSession();
Spring3.1集成Hibernate4不再需要HibernateDaoSupport和HibernateTemplate了,直接使用原生API即可。
四、通用Service层代码 此处省略,看源代码,有了通用代码后CURD就不用再写了。
java代码:
@Service("UserService")
public class UserServiceImpl extends BaseService&UserModel, Integer& implements UserService {
private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
private UserDao userD
@Autowired
@Qualifier("UserDao")
public void setBaseDao(IBaseDao&UserModel, Integer& userDao) {
this.baseDao = userD
this.userDao = (UserDao) userD
public Page&UserModel& query(int pn, int pageSize, UserQueryModel command) {
return PageUtil.getPage(userDao.countQuery(command) ,pn, userDao.query(pn, pageSize, command), pageSize);
五、表现层 Controller实现
采用SpringMVC支持的REST风格实现,具体看代码,此处我们使用了java Validator框架 来进行 表现层数据验证
在Model实现上加验证注解
java代码:
@Pattern(regexp = "[A-Za-z0-9]{5,20}", message = "{username.illegal}") //java validator验证(用户名字母数字组成,长度为5-10)
@NotEmpty(message = "{email.illegal}")
@Email(message = "{email.illegal}") //错误消息会自动到MessageSource中查找
@Pattern(regexp = "[A-Za-z0-9]{5,20}", message = "{password.illegal}")
@DateFormat( message="{register.date.error}")//自定义的验证器
private Date registerD
在Controller中相应方法的需要验证的参数上加@Valid即可
java代码:
@RequestMapping(value = "/user/add", method = {RequestMethod.POST})
public String add(Model model, @ModelAttribute("command") @Valid UserModel command, BindingResult result)
六、Spring集成测试
使用Spring集成测试能很方便的进行Bean的测试,而且使用@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)能自动回滚事务,清理测试前后状态。
java代码:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-config.xml"})
@Transactional
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
public class UserServiceTest {
AtomicInteger counter = new AtomicInteger();
@Autowired
private UserService userS
其他部分请直接看源码,欢迎大家讨论。
原创内容,转载请注明私塾在线【】
浏览 76283
论坛回复 /
(210 / 135092)
BaseHibernateDao 这个类好多红杠杠,哇?这个问题提示的是编译未通过。看了楼下的各种错误,找到了解决办法具体见/questions//method-is-ambiguous-for-the-type-but-the-types-are-not-ambigues-and-the-error 解决方法 在eclipse.ini -vmargs后面添加& -DtolerateIllegalAmbiguousVarargsInvocation=true 重启eclipse,并clean一下项目 重新编译即可,希望对之前 好几个人问的同一个问题有解决办法, 当然要是 楼主能编辑一下 在自己的文章里就好了,看了博客和论坛的这个文章 至少有5个以上的人遇到了这个问题。
BaseHibernateDao 这个类好多红杠杠,哇?我也遇到了同样的问题
w 写道请问下 这个工程有木有Myeclipse 的版本呢 谢谢。跟eclipse版本啥区别吗? 额,直接导入Myeclipse的话,项目的整个结构是乱的,呵呵,需要自己手动的一个个的去整理,很是麻烦啊。
请问下 这个工程有木有Myeclipse 的版本呢 谢谢。跟eclipse版本啥区别吗?
jinnianshilongnian 写道jiangpan 写道你好,想请教个问题,就是我在运行演示代码的时候,当修改信息后,点击提交时,速度比较慢,会等将近4秒钟,才会找到成功页面,这是什么原因恩?这个写个aop监控下 哪里慢老师,你好,你说的监控都需要监控哪些阶段?目前在我这的效果是,在页面中如果输入验证错误的信息时,点击提交,到显示错误信息的时间就很长,个人感觉,从点击提交到真正进入controller中的方法之间时间比较长,这个过程中各阶段的时间,应当怎么监控和优化?写个拦截器,监控下:1、从请求到控制器2、控制器执行3、执行完毕到视图渲染 4、整个期间的时间然后看看是哪阶段出问题了 再优化
jiangpan 写道你好,想请教个问题,就是我在运行演示代码的时候,当修改信息后,点击提交时,速度比较慢,会等将近4秒钟,才会找到成功页面,这是什么原因恩?这个写个aop监控下 哪里慢老师,你好,你说的监控都需要监控哪些阶段?目前在我这的效果是,在页面中如果输入验证错误的信息时,点击提交,到显示错误信息的时间就很长,个人感觉,从点击提交到真正进入controller中的方法之间时间比较长,这个过程中各阶段的时间,应当怎么监控和优化?
你好,想请教个问题,就是我在运行演示代码的时候,当修改信息后,点击提交时,速度比较慢,会等将近4秒钟,才会找到成功页面,这是什么原因恩?这个写个aop监控下 哪里慢
老师、Maven提示错误[ERROR] Failed to execute goal on project es-web: Could not resolve dependencies for project com.sishuok:es-web:war:1.0-SNAPSHOT: Could not transfer artifact com.sishuok:es-common:jar:1.0-SNAPSHOT from/to travis-ci-repo (http://maven.mirrors.travis-ci.org/nexus/content/repositories/central): Connection to http://maven.mirrors.travis-ci.org refused: Connection timed out: connect -& [Help 1]你是运行什么命令?
老师想问下这里的session形式的国际化是怎么弄的?建议使用cookie的国际化吧
老师想问下这里的session形式的国际化是怎么弄的?我这里没有 你google下 很多
& 上一页 1
jinnianshilongnian
浏览量:1413128
浏览量:1688657
浏览量:3254492
浏览量:153616
浏览量:869732
浏览量:168656
浏览量:2338044
浏览量:318121
下载的例子好像并不能切换数据源
关注后才发现,同事
这个项目的访问默认地址,直接输入http://localhos ...
System.out.println(&hel ...
jinnianshilongnian 写道carlosfu 写 ...