hibernate问题总结和学习

hql中in的参数设置:

String hql="FROM A WHERE A.ID IN (:alist)";   
Query query = getSession().createQuery(hql);   
query.setParameterList("alist", a); 

 

hibernate:java.lang.RuntimeException: duplicate method:

在Hibernate3.3后版本中,使用的字节码增强包默认是javassist了。而在3.2.6中默认使用的是cglib。要在3.3中更换为cglib,需要进行如下操作:
1. 在classpath下,添加hibernate.properties文件,并添加如下一行
hibernate.bytecode.provider=cglib
这行属性配置就是指定字节码生成包使用cglib。注意:
1) 一定要写成key=value形式,我按照Hibernate下载包中提供properties样板文件写成了hibernate.bytecode.provider cglib,死活不行。
2) 不能通过在hibernate.cfg.xml文件中配置:<property name="hibernate.bytecode.provider">cglib</property>来更换,一定要在hibernate.properties中配置才起效。
3). 添加cglib.jar到classpath中。Hibernate下载包中提供了cglib2.2.jar,但还需要添加cglib包依赖的asm3.1包。所以,干脆上cglib官网下载cglib-nodep-2.2.jar

org.hibernate.LazyInitializationException

解决方案一: 不使用懒加载
在配置文件或注解中,将懒加载设置为fetch=FetchType.EAGER或false。
这种做法,可能会把不需要的数据也加载上来,影响应用性能。

解决方案二: Open Session In View模式
利用过滤器(Filter),在用户请求结束、页面生成结束时关闭Session,保证在视图显示层一直打开Session。
这种做法也比较简单,似乎还不错,但是副作用却不容小视。在DAO层数据已经加载完毕后,数据库Connection在在用户请求结束、页面生成结束时才关闭。因而各种原因,如传输数据大、数据传输速率低等问题会导致数据库Connection长时间被占用不关闭,造成连接池不足、网页访问慢、网页假死等现象。

<filter>
     <filter-name>hibernateFilter</filter-name>
     <filter-class>
     org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
     </filter-class>
</filter
<filter-mapping>
     <filter-name>hibernateFilter</filter-name>
     <url-pattern>*.do</url-pattern>
</filter-mapping>


解决方案三:手动初始化数据
在关闭Session之前,初始化代理属性或者集合属性。如:
    for (Chapters chapter : book.getChapters());

当然这样代码可读性较差,Hibernate也提供了一种方法
    Hibernate.initialize(book.getChapters());

要在未关闭session之前调用该静态方法,不然会报 collection is not associated with any session

 

OpenSessionInViewFilter是spring提供的一个针对hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。
由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。

1)如果使用了OpenSessionInView模式,那么Spring会帮助你管理Session的开和关,从而你在你的DAO中通过HibernateDaoSupport拿到的getSession()方法,都是绑定到当前线程的线程安全的Session,即拿即用,最后会由Filter统一关闭。
2)由于拿到的Hibernate的Session被设置了session.setFlushMode(FlushMode.NEVER); 所以,除非你直接调用session.flush(),否则Hibernate session无论何时也不会flush任何的状态变化到数据库。因此,数据库事务的配置非常重要。(我们知道,在调用org.hibernate.Transaction.commit()的时候会触发session.flush())我曾经见过很多人在使用OpenSessionInView模式时,都因为没有正确配置事务,导致了底层会抛出有关FlushMode.NEVER的异常

 

出现a different object with the same identifier value was already associated with the session的错误的原因是

session中的对象的唯一标识符相同的冲突,其根本就是表现在数据库中的表格中的主键值相同的冲突或者其他唯一标识符冲突。解决这个冲突,我们必须知道,到底是哪个唯一标识符冲突,然后再去修改掉相同的标识符,

一般都是代码上下文中会出现新的new,设置了数据库中已有的id

 

Caused by: org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance

 

hibernate级联删除时候出现,举例:

将代码

  Set tbBuildings = new HashSet();
  tbBuildings.add(building2);
  hotel.setTbBuildings(tbBuildings); 

修改为:

  Set tbBuildings = hotel.getTbBuildings();
  tbBuildings.clear();
  tbBuildings.add(building2);

 

java.util.ConcurrentModificationException

对集合进行迭代的过程中修改元素,会导致此类错误

 

Criteria的完整用法:

http://www.cnblogs.com/mabaishui/archive/2009/10/16/1584510.html

 

级联删除

http://www.cnblogs.com/mfrbuaa/p/4590712.html

http://blog.csdn.net/zhh521125/article/details/5954137

 

并发的解决:乐观锁和悲观锁

http://www.cnblogs.com/otomedaybreak/archive/2012/01/27/2330008.html

http://blog.csdn.net/baungham/article/details/7228471

http://blog.csdn.net/liuguanghaoputin/article/details/2513087

 

事物隔离和并发控制:

http://blog.csdn.net/crazyitlhs/article/details/49446453

 

posted @ 2017-06-06 11:30  malcome  阅读(51)  评论(0)    收藏  举报