MyException - 我的异常网
当前位置:我的异常网» 软件架构设计 » Hibernate常见有关问题集锦(1)

Hibernate常见有关问题集锦(1)

www.MyException.Cn  网友分享于:2015-08-26  浏览:22次
Hibernate常见问题集锦(1)
Hibernate常见问题集锦

1问:Hibernate初始化时总是报错:java.lang.NoClassDefFoundError

 

Hibernate初始化时出现出错代码:
java.lang.NoClassDefFoundError: net/sf/ehcache/CacheException
答:这是新手常见问题。是因为使用默认设置时,Hibernate文档里指出的Hibernate库不完整,缺少ehcache.jar(用于支持 Ehcache的相关文件)。配置中加入以上文件,就可以避免初始化时出现java.lang.NoClassDefFoundError:net/sf /ehcache/CacheException异常。


2问:Hibernate报错:"Not binding factory to JNDI, no JNDI name configured"

 

运行下列程序:
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration().addClass(Person.class);
......
出现错误码:
12:15:34,250 INFO SessionFactoryObjectFactory:82 - Not binding factory to JNDI, no JNDI name configured
java.lang.UnsupportedOperationException: The user must supply a JDBC connection
at net.sf.Hibernate.connection.UserSuppliedConnectionProvider.getConnection (UserSuppliedConnectionProvider.java:32)
at net.sf.Hibernate.impl.BatcherImpl.openConnection(BatcherImpl.java:289)
at net.sf.Hibernate.impl.SessionImpl.connect(SessionImpl.java:3361)
at net.sf.Hibernate.impl.SessionImpl.connection(SessionImpl.java:3321)
at net.sf.Hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:66)
at net.sf.Hibernate.loader.Loader.prepareQueryStatement(Loader.java:779)
at net.sf.Hibernate.hql.QueryTranslator.iterate(QueryTranslator.java:864)
at net.sf.Hibernate.impl.SessionImpl.iterate(SessionImpl.java:1618)
at net.sf.Hibernate.impl.QueryImpl.iterate(QueryImpl.java:27)
at com.Hibernate.person.TestQueryPerson.main(TestQueryPerson.java:28)
Exception in thread "main"
答:修改main函数,为该程序指定配置文件即可。
public static void main(String[] args) throws Exception {
File file=new File("./Hibernate.cfg.xml");
Configuration conf = new Configuration().configure(file);
......
配置文件如下。
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://Hibernate.sourceforge.net/Hibernate-mapping-3.0.dtd ">
<hibernate-mapping package="org.Hibernate.test.array"></hibernate-mapping>
<class name="A" lazy="true"></class>

3问:使用开发工具Elipse,运行时总报java.lang.NoClassDefFoundError: org/ Hibernate/Session异常
使用Elipse,所用包是hibernte 3,发现在Action中每次执行到:
session=HibernateSessionFactory.currentSession();
时,出现java.lang.NoClassDefFoundError: org/Hibernate/Session异常,如下:
java.lang.NoClassDefFoundError: org/Hibernate/Session
Hibernate3.Hibernate.ExcuteClass.search(ExcuteClass.java:17)
Hibernate3.Hibernate.ExcuteClass.test3(ExcuteClass.java:13)
Hibernate3.Hibernate.Svlt.doGet(Svlt.java:50)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)[/b]
答:这是初学者常见问题,原因是没有导入hibernate 3.jar包,虽然把hibernate 3.jar写入了Classpath,但部署的时候却没有拷贝到lib下面,可以手动拷贝进入。


4问:执行如下方法时,发生"No CurrentSessionContext configured"错误
执行如下方法时,发生"No CurrentSessionContext configured"错误:
Public static Session currentSession() {
try {
System.out.println("HibernateUtil.currentSession() - start");
return getSessionFactory().getCurrentSession();
} catch (HibernateException ex) {
System.out.println("HibernateUtil.currentSession() - failed due to " + ex);
throw ex;
}
}
答:这个错误是由配置文件引起。在集成Hibernate的环境下(例如Jboss),在session-factory段加入:
<property name="Hibernate.current_session_context_class">jta</property>
在不集成Hibernate的环境下(例如使用JDBC的独立应用程序),在session-factory段加入:
<property name="Hibernate.current_session_context_class">thread</property>
就可以解决这个问题。


5问:移植Jboss 4下配置Hibernate出错
在Tomcat 5下配置Hibernate成功,但移植到Jboss 4下出现了很多问题。已在deploy目录下放置了Hibernate-service.xml和Hibernate.cfg.xml文件,但启动服务器仍然报错 如下。

 

16:56:54,046 ERROR [URLDeploymentScanner] Incomplete Deployment listing:
Packages waiting for a deployer:
org.Jboss.deployment.DeploymentInfo@24bd343 { url=file:/C:/Downloads/temp/Jboss-
4.0.0/server/default/deploy/Hibernate.cfg.xml }
deployer: null
status: null
state: INIT_WAITING_DEPLOYER
watch: file:/C:/Downloads/temp/Jboss-4.0.0/server/default/deploy/Hibernate.cfg
.xml
altDD: null
lastDeployed: 1113987414046
lastModified: 1113987414046
mbeans:
Incompletely deployed packages:
org.Jboss.deployment.DeploymentInfo@24bd343 { url=file:/C:/Downloads/temp/Jboss-
4.0.0/server/default/deploy/Hibernate.cfg.xml }
deployer: null
status: null
state: INIT_WAITING_DEPLOYER
watch: file:/C:/Downloads/temp/Jboss-4.0.0/server/default/deploy/Hibernate.cfg
.xml
altDD: null
lastDeployed: 1113987414046
lastModified: 1113987414046
mbeans:
答:这是在Jboss中使用Hibernate的常见问题。在Jboss的某个war包中使用Hibernate应该将 Hibernate.cfg.xml文件放置到%war_dir%WEB-INF/classes中,但是Hibernate的factory仍然可能会提示Hibernate.cfg.xml not found。此问题解决方法如下。
由于Jboss已经集成了Hibernate,在deploy\lib文件夹中hibernate2.jar的文件已经存在了一个jar包,所以实际的 war中可能使用了shar的hibernate2.jar,由于ClassLoader只会在hibernate2.jar的同级及上级目录中寻找 hibernate.cfg.xml,所以导致Hibernate并没有去查找%war_dir%WEB-INF/classes中的 Hibernate.cfg.xml文件。删除deploy/lib下的hibernate2.jar或者使用绝对路径指定 Hibernate.cfg.xml可以解决。
除非有其他需求,否则在Jboss下部署Hibernate与在Tomcat下是一样的,并不需要加其他配置文件。

 

6问:到底在哪里使用cascade="..."?

 

答:cascade属性并不是多对多关系一定要用的,用了它只是插入或删除对象时更方便一些,只要在cascade的源头上插入或删除,所有 cascade的关系就会被自动插入或删除。其中unsaved-value是个很重要的属性,Hibernate是通过这个属性来判断这个对象应该 “save”还是“update”,如果这个对象的id是unsaved-value,那说明这个对象不是persistence object,要save(insert);如果id是非unsaved-value,那说明这个对象是persistence object(数据库中已存在),只要update就行了。

 


7问:到底在哪里使用inverse="true"
答:inverse属性默认是false,就是说关系的两端都来维护关系。这个意思就是说,如有3个表:Student、Teacher和 TeacherStudent,Student对象和Teacher对象是多对多关系,这个关系由TeacherStudent表来表现。
那么什么时候插入或删除TeacherStudent表中的记录呢。用Hibernate时,不会显式的对TeacherStudent表操作,对 TeacherStudent的操作是Hibernate自动做的。Hibernate就是hbm文件中指定的是“谁”维护关系,在插入或删除时,就会触发对关系表的操作。前提是“谁”这个对象已经知道这个关系,就是说关系另一头的对象已经set或是add到“谁”这个对象里来。
前面说过inverse默认是false,就是关系的两端都维护关系,对其中任一个操作都会触发对表的操作。当在关系的一头,如Student中的bag 或set中用了inverse="true"时,就代表关系是由另一端维护的(Teacher)。就是说当插入Student时,不会操作 TeacherStudent表,即使Student已经知道了关系。只有Teacher插入或删除时才会触发对关系表的操作。所以,关系的两头都用 inverse="true"是不对的,会导致任何操作都不触发对关系表的操作。当两端都是inverse="false"或是default值时,在代码中对关系显式的维护也是不对的,会导致在关系表中插入两次关系。

 


8问:Cascade和Inverse有什么区别?

 

答:可以这样理解,Cascade定义的是关系两端对象到对象的级联关系;而Inverse定义的是关系和对象的级联关系。

 


9问:在删除操作时报错:net.sf.Hibernate.ObjectDeletedException:deleted object would be re-saved by cascade (remove deleted object from associations)

 

答:要删除关系的一头时(如,要删除一个已经和Student对象有关联的Teacher对象),当tx.commit()时才会抛出这个异常。防止出现这个异常的方法如下。
在Student端不用cascade。
或是用cascade的话,就显式的删除对像中的关系。
在Teacher端要用cascade。


10问:出现net.sf.Hibernate.HibernateException: identifier of an instance of my. MyObject altered from N to N异常

 

答:这个异常不是多对多关系中常遇到的,但是这个异常的提示容易让人混淆。这是因为在Java对象中,id定义和hbm文件的不一样。如Java中用long,而hbm中用type= "integer"。


11问:为什么在向数据库中插入长字符串时候部分自动丢失
在向数据库中增加一条新的条目时,发现如果文字(有英文字母,也有汉字)数量特别大,超过1000个,则每次通过Hibernate,向一个String类型的字段中增加数据时,只有几百个字可以增加进去,其他的自动丢失了。

答:这是由于字段长度设置不合理造成的。可以根据字符串实际长度考虑使用Text、LongText、或者Blob等字段类型。不同数据库的字段类型稍有不同,可以参考相关手册。另外需要注意的是一个汉字占用两个字节长度。

 

 

12问:为什么采用Hibernate的批量删除方法来删除大批量的记录数据时速度特别慢

答:在使用Hibernate版本2.X时,不推荐采用Hibernate的批量删除方法来删除大量记录。原因是,Hibernate会执行1条查询语句,另外还有满足条件的多条删除语句,而不是一次执行一个删除语句,所以当待删除的数据很多时,会有很大的性能瓶颈。而对于Hibernate 3.0以上的版本,则不存这个问题。

 

 

 

13问:升级Hibernate 3后在导入hbm映射文件时为什么非常非常慢

原先在Hibernate 2中,程序的速度是非常快的。当环境顺利从Hibernate 2升级到Hibernate 3后,发布时在Tomcat的控制台中发现:Hibernate 3装载hbm映射文件时非常慢,差不多10秒钟才能装载一个hbm文件。

答:通过在Hibernate的源代码中设置断点,可以发现执行效率低下的代码在org.hibernate.cfg.Configuration文件中的第240行:

addInputStream( new FileInputStream( xmlFile ) );

而addInputStream函数中又包含:

org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver ).read( new InputSource( xmlInputStream ) );

跟踪org.hibernate.util.XMLHelper中的函数createSAXReader可以得出结论,问题的症结出在这一条语句:

org.dom4j.Document doc = xmlHelper.createSAXReader()

可以判断这是在XML文件装载初始化时发生的错误,仔细检查XML文件,可以发现这是XML的第一行声明dtd的错误,因为以前使用的是 Hibernate 2,所以hbm文件的dtd指向的是版本2,而升级Hibernate 3后,没有把老的hbm映射文件换成版本3。在更换为3版本后,此问题得到解决。

 

 

14问:为什么Hibernate 3中的HQL无法查询汉字

使用同样的代码和配置文件,在Hibernate 2上完全没有问题,在Hibernate 3中,使用如下HQL查询,无法得到正确的结果集:

String hql = "from story where title like '%汉字%'";

Query q = session.createQuery(hql);

但用下面的HQL查询,却可以得到正确结果集:

String hql = " from story where title like '%english%'";

Query q = session.createQuery(hql);

答:如果采用的是拼接HQL的方式,从Hibernate 2升级到Hibernate 3确实会出现汉字乱码问题。在控制台中可以看到,SQL的汉字部分变成了乱码:

[DEBUG] 2005-08-14 14:33:58 org.hibernate.SQL - "select story0_.content from story as story0_ where story0_.title like '%&–°é—&&`¨&'

在Hibernate中,查询时应尽量使用占位符的写法(如下),这样既可以避免乱码问题,又可以避免潜在的SQL注入攻击:

 

getHibernate().find("from story where title like ? ", "%汉字%")

 

 

 

15问:Hibernate 3中如何获得库表所有字段的名称

答:可以使用以下的程序获得。

Configuration conf = new Configuration();

conf.configure();

Iterator iter = conf.getTableMappings();

 

while ( iter.hasNext() ) {

Table table = ( Table ) iter.next();

 

System.out.println(table.getName());

Iterator ics = table.getColumnIterator();

while (ics.hasNext()){

Column col = (Column) ics.next();

System.out.println(col.getName());

}

 

 

16问:错误代码:ObjectNotFoundException: No row with the given identifier exists

答:在以下几种情况下,该错误可能会发生。

当试图使用session.load()方法装载一个未被代理的对象,或者访问一个超出范围的代理对象时。

当装载一个未被正确取得的映射时。

当未被外键约束的外键字段中含有非法值时。

检查装载使用的主键Id,并验证外键关系,以确定数据库中已经存在相应的约束关系。坚持“在一个Session中只处理一个事务”的原则。因为当在单一Session中使用多个事务时很容易犯错。尤其注意,在一个HibernateException已经抛出后不要再操作Session。

 

 

17问:错误代码:InvalidObjectException: Could not find a SessionFactory named: null

答:这个错误在以下几种情况下经常发生。

试图序列化一个已经失效的Hibernate Session,然后在另外一个虚拟机中进行反序列化。

类装载器被重置,例如在未重启的application server或者Web container中重新部署程序。在使用Tomcat时会经常遇到这个问题,这是因为application server中一般使用JNDI来存储SessionFactory,而在Tomcat或其他一些Web容器中,则是通过在context重载时,关闭 HttpSession序列化来实现的。这种实现方式会引起这个错误发生。

 

18问:错误代码:org.hibernate.HibernateException: CGLIB Enhancement failed: <classname></classname>

答:Hibernate 3的默认方式是把所有类通过代理方式来进行延迟加载。如果代码中的类有一个私有无参的构造器的话,Hibernate将无法在运行时将项目代码中的类作为子类装载。为了避免这个错误,类中的构造器函数至少应该在包内可见。

 

 

19问:为什么在Hibernate中添加、删除、修改一个对象或Collection,但是数据库中实际上没有任何变化

 

答:这个问题经常会困扰初学者。这是因为如果没有使用Hibernate的自动事务处理,则必需显式的提交事务,操作才会在数据库中执行。

 

 

20问:为什么保存一个父对象,而它的关联对象没有自动储存到数据库里

答:关联对象必需显式的调用session.save()(或session.persist()),或者在关联的映射文件中加入cascade="all"或cascade="save-update"(或cascade="persist")才能够自动关联执行。

 

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="">,其中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()方法:用于把命名参数与一个对象的属性值绑定时,对象中没有匹配的名字相同的属
性。

文章评论

团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
程序员和编码员之间的区别
程序员和编码员之间的区别
我是如何打败拖延症的
我是如何打败拖延症的
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
为什么程序员都是夜猫子
为什么程序员都是夜猫子
 程序员的样子
程序员的样子
中美印日四国程序员比较
中美印日四国程序员比较
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
每天工作4小时的程序员
每天工作4小时的程序员
旅行,写作,编程
旅行,写作,编程
如何成为一名黑客
如何成为一名黑客
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
那些争议最大的编程观点
那些争议最大的编程观点
代码女神横空出世
代码女神横空出世
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
Java程序员必看电影
Java程序员必看电影
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
程序员的鄙视链
程序员的鄙视链
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
总结2014中国互联网十大段子
总结2014中国互联网十大段子
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
鲜为人知的编程真相
鲜为人知的编程真相
程序员应该关注的一些事儿
程序员应该关注的一些事儿
一个程序员的时间管理
一个程序员的时间管理
我的丈夫是个程序员
我的丈夫是个程序员
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
编程语言是女人
编程语言是女人
程序员都该阅读的书
程序员都该阅读的书
漫画:程序员的工作
漫画:程序员的工作
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有