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 ></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)
 
答:这是初学者常见问题,原因是没有导入 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")才能够自动关联执行。



本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/archive/2010/12/20/1911945.html,如需转载请自行联系原作者

目录
相关文章
|
10天前
|
数据可视化 Go vr&ar
JCR一区7.4分|教科书般网药四件套+实验验证,廉颇老矣尚能饭否
该文章是一篇发表在《Journal of Translational Medicine》上的研究,探讨了白藜芦醇治疗糖尿病肾病(DKD)的机制。通过网络药理学、分子对接和实验验证,研究发现白藜芦醇可能通过作用于PPARA、SHBG、AKR1B1、PPARG、IGF1R、MMP9、AKT1和INSR等靶点影响DKD。分子对接和细胞实验进一步证实了这些发现,为白藜芦醇在DKD治疗中的应用提供了理论支持。
23 0
|
8月前
|
消息中间件 缓存 安全
讲理论,重实战!阿里独家SpringBoot王者晋级之路小册,太强了!
大家平时学习SpringBoot的方式也一般是看大量博客或者是找一些业界评价好点的书籍,虽然SpringBoot相关资料很多,但是大多不成体系,很少有真正有能从0到1,详解Spring Boot一切从代码案例出发的案头笔记。 今天给小伙伴分享的就是来自阿里的SpringBoot王者晋级之路小册,这份小册从SpringBoot的开发环境部署开始,把Spring Boot搭建Web项目、操作数据库、使用缓存、日志、整合安全框架、结合消息队列和搜索框架,以及在实际应用中的部署全部讲得清清楚楚。
|
11月前
|
SQL XML 存储
MyBatis这样用,同事直呼哇塞,堪称最佳实践
MyBatis是一款非常流行的ORM框架,相信很多小伙伴都在使用。我们经常会把它和MyBatis-Plus或者MBG一起使用,用多了之后对于其一些常规操作就不太熟悉了。最近总结了下MyBatis的实用用法和技巧,希望对大家有所帮助!
|
前端开发 Oracle 算法
卷王必备学习的MyBatis-Plus用法,不来瞧瞧吗~~
卷王必备学习的MyBatis-Plus用法,不来瞧瞧吗~~
115095 1
卷王必备学习的MyBatis-Plus用法,不来瞧瞧吗~~
加班有几种情况?兼谈讨论的方式。
  加班有几种情况? 工作狂 —— 为了工作自愿加班。 被动型 —— 没能按时完成任务,不得不加班。有可能是自己手慢,也可能是任务安排不合理,也可能是客户根本就没有给出合理的时间。 学习型 —— 利用公司的资源(电脑、网络等)来学习,给自己充电。
860 0
|
Dubbo 测试技术 应用服务中间件
[雪峰磁针石博客]使用jython进行dubbo接口及ngrinder性能测试
快速入门(接口测试) 确认mvn和jdk、jython安装ok。 先下载dubbo的demo,编译运行demo。 # git clone https://github.com/alibaba/dubbo.

相关实验场景

更多