Hibernate 常见异常
net.sf.hibernate.MappingException
当出现net.sf.hibernate.MappingException: Error reading resource:…异常时通常是由于映射文
件出现错误。
当出现net.sf.hibernate.MappingException: Resource: … not found是由于XML配置文件没找到所致,有多是放置目录不正确,或者没将其加入hibernate.cfg.xml中。
2. net.sf.hibernate.PropertyNotFoundException
当出现net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property
name in class …时,缘由通常是由于XML映射文件中的属性与对应的Java类中的属性的getter或setter方法不一致。
3. org.hibernate.id.IdentifierGenerationException
当出现org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():异常时,通常是由于<id>元素配置不正确,<id>元素缺乏其子元素<generator></generator>的配置引发。
解决方案:<id>元素映射了相应数据库表的主键字段,对其子元素<generator >,其中class
的取值能够为increment、identity、sequence、hilo、native……等,更多的可参考hibernate参考文档,通常取其值为native 。具体可参考2.2.2.1小节。
4. a different object with the same identifier value was already associated with the session
当出现a different object with the same identifier value was already associated with the
session时,通常是由于在hibernate中同一个session里面有了两个相同标识可是是不一样实体。
有以下几种解决方案:
(1)使用session.clean(),若是在clean操做后面又进行了saveOrUpdate(object)等改变数据状态的操做,有可能会报出"Found two representations of same collection"异常。
(2)使用session.refresh(object),当object不是数据库中已有数据的对象的时候,不能使用
session.refresh(object)由于该方法是从hibernate的session中去从新取object,若是session中没有这个对象,则会报错因此当你使用saveOrUpdate(object)以前还须要判断一下。
(3)session.merge(object),Hibernate里面自带的方法,推荐使用。
再次碰到:a different object with the same identifier value was already associated with the
session这个错误我一共遇到过两次,一直没有找到很好的解决方案,这个错误产生缘由相信你们都知道,由于在hibernate中同一个session里面有了两个相同标识可是是不一样实体.
一开始按网上说的用session.merge(Object)报了一个错,多是没有用好,改用 session.clear();
session.update(user);这样就OK了,
方法为:
package org.springframework.orm.hibernate3.support;
...
public void modifyByMerge(User user) {
Session session = getHibernateTemplate().getSessionFactory().
getCurrentSession();
session.clear();
session.update(user);
}
...
项目用的是spring + hibernate因此得用getHibernateTemplate().getSessionFactory
().getCurrentSession();得当前Session
5. SQL Grammer Exception,Could not execute JDBC batch update
当出现SQL Grammer Exception,Could not execute JDBC batch update异常时,通常是由以下问题
引发:
(1)SQL语句中存在语法错误或是传入的数据有误;
(2)数据库的配置不合法,或者说是配置有误。较容易出现的有数据表的映射文件(,hbm.xml文件)配置有误
;Hibernate.cfg.xml文件配置有误;
(3) 当前的数据库用户权限不足,不能操做数据库。以是以Oracle 数据库为例,这种状况下在错误提示中
会显示java.sql.BatchUpdateException: ORA-01031: insufficient privileges这样的信息。
针对上面的各类缘由,开发人员能够找出对应的解决方案。
16.net.sf.hibernate.QueryException: undefined alias:我猜测出项这种错误的缘由有不少种:多是大小写问题,还有其余不少种可能
17.net.sf.hibernate.NonUniqueResultException:检索单个对象时,查询结果包含多个对象,但没有调用
setMaxResult(1)方法
18.net.sf.hibernate.QueryException: Not all named parameters have been set
使用setProperties()方法:用于把命名参数与一个对象的属性值绑定时,对象中没有匹配的名字相同的属
性。
文章出处:http://www.diybl.com/course/3_program/java/javashl/2008410/108844_2.html
===========================
1 .Caused by: org.dom4j.DocumentException: Invalid byte 2 of 2-byte UTF-8 sequence. Nested
exception: Invalid byte 2 of 2-byte UTF-8 sequence.
若是出现这行错误说明你的XML配置文件有不规范的字符,检查下。
2 .net.sf.hibernate.MappingException: Error reading resource: hibernate/Hello_Bean.hbm.xml
若是出现这行错误说明你的hibernate的XML配置文件有错
3 .net.sf.hibernate.MappingException: Resource: hibernate/Hello_Bean.hbm.xml not found
若是出现这行错误说明hibernate的XML配置文件没有找到,你应该把XML文件放在与你的类文件同个目录下,
本文中是放在hibernate\classes\hibernate\目录下,也就是跟Hello_Bean.class类文件一块儿。
4 .net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property name in class hibernate.Hello_Bean
若是出现这行错误说明你的xml文件里设置的字段名name的值与Hello_Bean.Java类里的getXXX或setXXX方法不一致。
5 .net.sf.hibernate.HibernateException: JDBC Driver class not found: org.gjt.mm.mysql.Driver
6.The database returned no natively generated identity value 。 主键没有添加增量
===========================
Exception : No form found under 'loginForm' in locale 'en_US'
这个错误彻底是我本身给本身找麻烦,我在给loginForm作表单验证时,用了validator,我在写
validation.xml文件时,忽然发神经,想写得比较国际化一点,这样写的:
<formset language="zh" country="CN"> <!--这个是zh_CN的-->
开始是一点问题都没有,由于咱们你们通常都用中文系统,后来有一天我用linux,当时环境是english,
结果发现页面就报错:No form found under 'loginForm' in locale 'en_US'。
当时,特别郁闷,后来仔细回忆,想起当时只在validation.xml文件里显式的写过国际化相关的东西,后来
就把 language="zh" country="CN" 给删掉了。即:
<formset>。。。。。。</formset>
再用英文系统访问就没有事情了,看来你要是想国际化,就把全部的状况的配置都写全了,不要只指定中文
的配置,英文的不配置,那样,别人用英文系统的人就会出错。因此,建议仍是不要制定国际化,看来有的
时候仍是偷懒一点比较好!
===========================
Hibernate错误:org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
缘由多半是你的mapping文件的主键没有设置对。检查以下:
一:看你的主键类型是什么?若是是long,int等,记得设置unsaved-value="0"
二:若是是string 的话,请设置unsaved-value="null"
注意unsaved-value是个很重要的属性。Hibernate经过这个属性来判断一个对象应该save仍是update,若是这个对象的id是unsaved-value的话,那说明这个对象不是 persistence object要save(insert);若是id是非unsaved-value的话,那说明这个对象是persistence object(数据库中已存在),只要update就好了。
你能够Debug跟一下你的代码,看看在 session.update(obj); 的时候,obj的主键的值是否是按你定义的那
样,obj能够被hibernate认为是一个已经持久化在数据库里的对象
===========================================================
java.lang.NoClassDefFoundError: antlr/ANTLRException
缘由是:缺乏antlr-2.7.5H3.jar
---------------------------------------2----------------------------------------------
类 java.lang.NoSuchMethodError
java.lang.Object
|
+----java.lang.Throwable
|
+----java.lang.Error
|
+----java.lang.LinkageError
|
+----java.lang.IncompatibleClassChangeError
|
+----java.lang.NoSuchMethodError
public class NoSuchMethodError
extends IncompatibleClassChangeError
若是应用程序试图调用一个类的指定方法(不管是静态仍是动态),可是该类再也不有该方法的定义,则抛出该
异常。
一般由编译器检测此错误;若是类定义不容许再做兼容性的改变,那么此错误只可能发生在运行时刻。
构造子索引
NoSuchMethodError()
NoSuchMethodError(String)
用指定的详细信息构造 NoSuchMethodException。
构造子
NoSuchMethodError
public NoSuchMethodError()
NoSuchMethodError
public NoSuchMethodError(String s)
用指定的详细信息构造 NoSuchMethodException。
参数:
s - 详细信息。
----------------------------------3--------------------------------------------------
今天用hibernate3作关系映射,当调用映射类的时候老是报
org.hibernate.LazyInitializationException: could not initialize proxy错误
缘由:
hb3对many-to-one的默认处理是lazy = "proxy" 而hb2是false
因此,要这么设置
<many-to-one column="sort_id"
cascade="all" outer-join="true" lazy="false" />
------------------------------------4--------------------------------------------------
java.sql.Timestamp异常
缘由:时间date错误
更改时间java.util.Date 为java.lang.String就行了,同时修改配置文件中的内容
------------------------------------5--------------------------------------------------
Cannot find bean in any scope
分类:Struts异常
1.出现这种错误通常是资源文件没找到或是资源文件里没有对应的key值。
2.struts-config.xml里的Action配置里把redirect设置为了true;改为false,
3.在Action里通常会request.setAttribute()一些对象,而后在转向的jsp文件里
(用tag或 request.getAttribute()方法)获得这些对象并显示出来。
这个异常是说jsp要获得一个对象,
但前面的Action里并无将对象设置到request(也能够是session、servletContext)里。
多是名字错了,请检查jsp里的tag的通常是name属性,或getAttribute()方法的参数值;
或者是Action逻辑有问题没有执行setAttribute()方法就先转向了。
还有另一个可能,纯粹是jsp文件的问题,例如<logic:iterate>会指定一个id值,
而后在循环里<bean:write>使用这个值做为name的值,若是这两个值不一样,
也会出现此异常。(都是一个道理,request里没有对应的对象。)
4.这个状况比较特殊,应该算没有把STRUTS标记库的机制搞明白,
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
若是没有在头声明这个就用logic:iterate标记,
在bean:write的时候就会出异常!
---------------------------------6----------------------------------------------------
HibernateException: Not able to obtain connection
org.hibernate.HibernateException: Not able to obtain connection
差很少等于没有链接数据库了。要保证Hibernate的Session工厂能正常工做。
这个通常咱们的作法是Session工厂设置成静态的。
而后须要进行操做就打开一个会话。因此在设计的时候注意一下。这个Session工厂对象。
最好是放在
static{}块里。而后用个抽象类去实现它,而后其余的类都实现这个抽象类就搞定了!
---------------------------------7----------------------------------------------------
org.hibernate.MappingException: Error reading resource: XXXX.XML
这个异常出现的报错还有:
Could not configure datastore from input stream
org.dom4j.DocumentException: xxxxx(系统找不到指定的文件。) Nested exception: xxxx
org.hibernate.MappingException: Error reading resource: xxxx
这个异常主要出现的状况有:
(1)没有映射文件,也就是没有xxx.hbm.xml
(2)在xxx.hbm.xml文件中有错误,主要多是书写错误,或有乱码
(3) 这个问题最恶心,通常人不会注意到,就是要注意配置文件和映射文件都必须用同一个版本的HIBERNATE
,怎么看是否用同一个HIBERNATE呢,你能够查看hibernate.cfg.xml和xxx.hbm.xml开头内容:
例如
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
若是一个是2.0一个是3.0到时候DOM4J就会出异常。解析不了咯!
---------------------------------------8-----------------------------------------------
save the transient instance before flushing
1.
(1)作Hibernate多对一的时候,报错:
org.apache.jasper.JasperException: Error creating bean with name 'sf' defined in ServletContext
resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is
org.hibernate.PropertyNotFoundException: Could not find a getter for person in class
com.accp.vo.Course
由于配置文件中的一个 <many-to-one ../> 中的person属性名称写错了.
还有缘由以下:
1)getter()方法写错了,没有按照javaBean的规则写.
2)*.hmb.xml中的属性名和pojo中的是否一致.注意:属性名是否多了空格.
(2).Hibernate多对一报错:
save the transient instance before flushing
具体错误为在one-to-many中,对many进行save时,因为没有加入one的外建,致使错误。
具体解决方法:
(1)、在one的hbm文件中 invest=true
(2)、在many保存前务必要求one的存在
---------------------------------------9-----------------------------------------------
Named query not known
在使用session.getNamedQuery("XXX");执行HQL语句的时候,没有找 XXX语句,这主要是2个缘由
1:粗心,把名给写错了
2:XXX的HQL语句所在的.hbm.xml没有在hibernate.cfg.xml里注册过!
---------------------------------------10----------------------------------------------
Expected positional parameter count: X, actual parameters:
org.hibernate.QueryException: Expected positional parameter count: 2, actual parameters: []
[SELECT * from Ad where gr_id = ? and adst_id = ?]
这样的异常主要缘由是:
//如下为例子
Query query =session.getNamedQuery("OnlienAd");
query.setParameter(0,gray.getId());
query.setParameter(1,Globals.UPED_STATE);
能够看到query.setParameter()设置了位,也能够理解成他在要执行的HQL语句中占了2个位置。
而后执行的时候会对应HQL里的?中去。
若是你并无setParameter(),但你的HQL里却有?那么就会出这个异常。
---------------------------------------11---------------------------------------------
org.hibernate.MappingException: Association references:XXX
---------------------------------------12---------------------------------------------
org.hibernate.exception.SQLGrammarException: could not initialize
没法实例集合。
这个是问题在你当前的实体中有一个一对多需实例的对象。但这个对象却没法实例出来,说明一对多那个多
的一方实体有问题,多数状况可能有:
一、数据库该动过但代码没动
二、实体代码有错误
---------------------------------------13---------------------------------------------
org.hibernate.id.IdentifierGenerationException
异常信息:org.hibernate.id.IdentifierGenerationException: ids for this class must be manually
assigned before calling save():
异常缘由:
<id>元素配置不正确,
<id>元素缺乏其子元素<generator></generator>的配置。
解决方法:<id>元素映射了相应数据库表的主键字段,对其子元素<generator >,其中class的取值
能够为increment、identity、sequence、hilo、native...... 等,更多的可参考hibernate参考文档,通常
取其值为native 。
MySQL:identity,increment,hilo,native.
SQL Server:identity,increment,hilo,native.
Oracle:sequence,seqhilo,increment,native.
跨平台开发:native.
native将字段管理交给数据库本身定义。
---------------------------------------8-----------------------------------------------
not-null property references a null or transient value
此异常出现看开头就个单词就知道啦
的实体约束不能为空却为空形成的,那我在这说一下对于这样的状况咱们时常犯的错误。
咱们在对实体进行更新操做时最好是在一个会话中将数据从数据库中调出并实例BEAN的对象。
而后再对此对象进行更改后在更新。
这样的好处是:
1、数据是最新鲜的。
2、避免没必要要的设置,特别是在一对多和多对多的状况下,好比你如今操做的实体并非在一个会话中得
到,而是保存在某些容器中,好比jsp的 SESSION中,虽然这样的实体对象中有不少数据,可是若是你想获得
这些实体对应的1对多或多对1的实体时,就会发现会出现session已经关闭的异常。或则在你更新数据时出现
not-null异常等。
---------------------------------------14----------------------------------------------
Remember that ordinal parameters are 1-based!
HQL语句有错误
---------------------------------------15---------------------------------------------
failed to lazily initialize a collection of role: XXXXXXXX no session or
这个异常大体意思是说在多对一的时候(而且lazy="false"),对象的实例失败,多数出现的状况有
一、粗心形成
实例对象类名写错之类的
二、逻辑错误
如以前就已经传递过来一个实体对象,而后调用实体对象的方法时牵涉到1对多的状况,但此时SESSION已经
关闭,因此根本没法进行一对多的操做。
三、设计到跨度的问题:
这样打比方有多个实体对象,他们直接或则间接的有关联。好比有4个实体,分别是广告信息、广告、广告问
答题、广告商:他们之间的关系为:
广告商 1:n 广告
广告 1:n 广告问答题
广告商 1:n 广告商信息
你们能够看到广告和广告商信息是没有直接关系的。但我要添加广告的时候我就必须将广告商的实体作为条
件。那么这么一来广告商信息可能间接的就必须用上。下面看个人操做:
ad(广告),subject(题目)
Ad ad = new Ad();
ad.setAdProd(adform.getAdProd());
ad.setIndustry(industry);
ad.setAdPicture(pagefile.getFileName());
ad.setAdFlack(adform.getAdFlack());
ad.setAdDv(dvfile.getFileName());
ad.setAdContent(adform.getAdContent());
ad.setGray(gray);
ad.setAdDate(new Date());
ad.setOnlinetime(new Long(0));
//以上为广告的基本信息填写,而重要的是看下面一句,在这里个人思路是subjectFormList是一个动
态提交的表单,里面有若干个广告问答题。我将这些问答题变为一个Set,而后做为ad的一个属性。
Set<Subject> subjectset=getSubjectSet(subjectFormList,ad);
ad.setSubjects(subjectset);
//而后提交,makePersistent是一个封装的方法,用途就是save()啦。addao是一个DAO,里面有ADUS。
addao.makePersistent(ad);
表面上看来很符合逻辑,只要咱们在ad的映射里面加上对subject的级联更新就能够完成这项操做。但实际上
会发生咱们意想不到的问题,来让咱们看一下getSubjectSet()的内容:
public Set getSubjectSet(List<SubjectForm> subjectlist,Ad ad)
{
Set<Subject> set=new HashSet<Subject>(0);
Subject subject;
for(Iterator<SubjectForm> it=subjectlist.iterator();it.hasNext();)
{
subject=new Subject();
SubjectForm sf=it.next();
subject.setSuContent(sf.getSucontent());
subject.setSuOption(sf.getSuoption());
subject.setSuResult(Arrays.deepToString(sf.getSuresult()));
subject.setSuType(String.valueOf(sf.getSutype()));
subject.setAd(ad);
set.add(subject);
}
return set;
}
咱们在这个方法上设一个断点而后跟踪,以后你会发现断点在set.add(subject)只后就会出failed to
lazily initialize a collection of role: XXXXXXXX no session or session was closed这个异常,而且
这个异常仍是出在了广告商的广告信息上 gray.messages。是否是很不可理解?这也是Hibernate的懒汉机制问题。没有任何同样技术是完美的。那咱们该怎么处理这样的问题。有不少人觉得咱们在广告商对广告商信
息的隐射上加lazy="false"这样在对gray操做会对messages进行关联,并查询时提出数据。但你会发现改完以后会出现org.hibernate.LazyInitializationException: illegal access to loading collection这个异
常。并切lazy="false"是咱们不推荐的一种方法。他会下降你的查询效率。
对于这样的状况最好的解决办法就是不要偷懒,对一个实体进行操做的时候就该用那个实体的DAO,即应该有
2句HQL。以下把getSubjectSet()改一改:
public void getSubjectSet(List<SubjectForm> subjectlist,Ad ad)
{
Set<Subject> set=new HashSet<Subject>(0);
SubjectDAO subjectdao=DAOFactory.getDao(SubjectDAO.class);
for(Iterator<SubjectForm> it=subjectlist.iterator();it.hasNext();)
{
Subject subject=new Subject();
SubjectForm sf=it.next();
subject.setSuContent(sf.getSucontent());
subject.setSuOption(sf.getSuoption());
subject.setSuResult(Arrays.deepToString(sf.getSuresult()));
subject.setSuType(String.valueOf(sf.getSutype()));
subject.setAd(ad);
subjectdao.makePersistent(subject);
//set.add(subject);
}
}//遍历出全部subject一个个的往数据库里加。这样便不会出问题了。
一、OpenSessionInView模式:
如下有2种方法,第1种是结合SPRING,第2种是采用了拦截器
Spring+Hibernate中,集合映射若是使用lazy="true", 当PO传到View层时, 出现未初始化session已关闭的错误,只能在dao先初始化
parent.getChilds().size();
Spring提供Open Session In View来解决这个问题, 有两种方式
1. Interceptor
<!--</span><span style="COLOR: rgb(0,128,0)"> =========== OpenSession In View pattern
==============</span><span style="COLOR: rgb(0,128,0)">-->
<bean
>
<property ref="sessionFactory"/>
</bean>
<bean
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property ref="openSessionInViewInterceptor"/>
<property >
<props>
......
</props>
</property>
</bean>
2. Filter
<web-app>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
</web-app>
第2种解决方法:
Hibernate.initialize()强制加载关联对象
---------------------------------------16----------------------------------------------
Hibernate的No CurrentSessionContext configured 解决方案
Hibernate No CurrentSessionContext configured!
当你使用 Hibernate session factory的getCurrentSession() 函数时候,你可能见到过"No
CurrentSessionContext configured!"
出现这个问题,是由于你没有正确配置 Hibernate internal session context management .
你只要在Hibernate.cfg.xml文件中添加下面的配置就能够了:
<property >thread</property>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^
hibernate实现类中的方法2009-02-22 12:52--增长
public void addUser(User user){
Session s=null;
Transation tx=null;
try{
s=HibernateUtil.getSession();//在HibernateUtil工具类中写的
tx=s.beginTransation();
s.save(user);//要是删除操做就改为s.delete(user);要是更新:s.update(user);
tx.commit();
}catch(hibernateException e){
if(tx!=null){tx.rollback();}
trow e;
}finally{
if(s!=null){s.close();}
}
}html