hibernate常见异常总结

问: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"
运行下列程序:
1. public static void main(String[] args) throws Exception {
2. Configuration conf = new Configuration().addClass(Person.class);
3. ......
出现错误码:
1. 12:15:34,250 INFO SessionFactoryObjectFactory:82 - Not binding factory to JNDI, no JNDI name configured
2. java.lang.UnsupportedOperationException: The user must supply a JDBC connection
3. at net.sf.Hibernate.connection.UserSuppliedConnectionProvider.getConnection (UserSuppliedConnectionProvider.java:32)
4. at net.sf.Hibernate.impl.BatcherImpl.openConnection(BatcherImpl.java:289)
5. at net.sf.Hibernate.impl.SessionImpl.connect(SessionImpl.java:3361)
6. at net.sf.Hibernate.impl.SessionImpl.connection(SessionImpl.java:3321)
7. at net.sf.Hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:66)
8. at net.sf.Hibernate.loader.Loader.prepareQueryStatement(Loader.java:779)
9. at net.sf.Hibernate.hql.QueryTranslator.iterate(QueryTranslator.java:864)
10. at net.sf.Hibernate.impl.SessionImpl.iterate(SessionImpl.java:1618)
11. at net.sf.Hibernate.impl.QueryImpl.iterate(QueryImpl.java:27)
12. at com.Hibernate.person.TestQueryPerson.main(TestQueryPerson.java:28)
13. Exception in thread "main"
答:修改main函数,为该程序指定配置文件即可。
1. public static void main(String[] args) throws Exception {
2. File file=new File("./Hibernate.cfg.xml");
3. Configuration conf = new Configuration().configure(file);
4. ......
配置文件如下。
1. <?xml version="1.0"?>
2. <!DOCTYPE Hibernate-mapping PUBLIC
3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4. "http://Hibernate.sourceforge.net/Hibernate-mapping-3.0.dtd">
5. <!--
6. This mapping demonstrates content-based discrimination for the
7. table-per-hierarchy mapping strategy, using a formula
8. discriminator.
9. -->
10. <Hibernate-mapping package="org.Hibernate.test.array">
11. <class name="A" lazy="true">
12. <id name="id">
13. <generator class="native"/>
14. </id>
15. <array name="bs" cascade="all" fetch="join">
16. <key column="a_id"/>
17. <list-index column="idx"/>
18. <one-to-many class="B"/>
19. </array>
20. </class>
21. <class name="B" lazy="true">
22. <id name="id">
23. <generator class="native"/>
24. </id>
25. </class>
26. </Hibernate-mapping>
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"错误:
1. Public static Session currentSession() {
2. try {
3. System.out.println("HibernateUtil.currentSession() - start");
4. return getSessionFactory().getCurrentSession();
5. } catch (HibernateException ex) {
6. System.out.println("HibernateUtil.currentSession() - failed due to " + ex);
7. throw ex;
8. }
9. }

答:这个错误是由配置文件引起。在集成Hibernate的环境下(例如Jboss),在session-factory段加入:
1. <property name="Hibernate.current_session_context_class">jta</property
在不集成Hibernate的环境下(例如使用JDBC的独立应用程序),在session-factory段加入:
1. <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文件,但启动服务器仍然报错 如下。
1. 16:56:54,046 ERROR [URLDeploymentScanner] Incomplete Deployment listing:
2. Packages waiting for a deployer:
3. org.Jboss.deployment.DeploymentInfo@24bd343 { url=file:/C:/Downloads/temp/Jboss-
4. 4.0.0/server/default/deploy/Hibernate.cfg.xml }
5. deployer: null
6. status: null
7. state: INIT_WAITING_DEPLOYER
8. watch: file:/C:/Downloads/temp/Jboss-4.0.0/server/default/deploy/Hibernate.cfg
9. .xml
10. altDD: null
11. lastDeployed: 1113987414046
12. lastModified: 1113987414046
13. Incompletely deployed packages:
14. org.Jboss.deployment.DeploymentInfo@24bd343 { url=file:/C:/Downloads/temp/Jboss-
15. 4.0.0/server/default/deploy/Hibernate.cfg.xml }
16. deployer: null
17. status: null
18. state: INIT_WAITING_DEPLOYER
19. watch: file:/C:/Downloads/temp/Jboss-4.0.0/server/default/deploy/Hibernate.cfg
20. .xml
21. altDD: null
22. lastDeployed: 1113987414046
23. lastModified: 1113987414046
24. 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行:
1. addInputStream( new FileInputStream( xmlFile ) );
而addInputStream函数中又包含:
复制代码
1. org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver ).read( new InputSource( xmlInputStream ) );
跟踪org.hibernate.util.XMLHelper中的函数createSAXReader可以得出结论,问题的症结出在这一条语句:
1. 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查询,无法得到正确的结果集:
1. String hql = "from story where title like '%汉字%'";
2. Query q = session.createQuery(hql);
但用下面的HQL查询,却可以得到正确结果集:
1. String hql = " from story where title like '%english%'";
2. 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中如何获得库表所有字段的名称
答:可以使用以下的程序获得。
1. Configuration conf = new Configuration();
2. conf.configure();
3. Iterator iter = conf.getTableMappings();
4.
5. while ( iter.hasNext() ) {
6. Table table = ( Table ) iter.next();
7.
8. System.out.println(table.getName());
9. Iterator ics = table.getColumnIterator();
10. while (ics.hasNext()){
11. Column col = (Column) ics.next();
12. System.out.println(col.getName());
13. ; }
14. }
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>
答:Hibernate 3的默认方式是把所有类通过代理方式来进行延迟加载。如果代码中的类有一个私有无参的构造器的话,Hibernate将无法在运行时将项目代码中的类作为子类装载。为了避免这个错误,类中的构造器函数至少应该在包内可见。
19问:为什么在Hibernate中添加、删除、修改一个对象或Collection,但是数据库中实际上没有任何变化
答:这个问题经常会困扰初学者。这是因为如果没有使用Hibernate的自动事务处理,则必需显式的提交事务,操作才会在数据库中执行。
20问:为什么保存一个父对象,而它的关联对象没有自动储存到数据库里
答:关联对象必需显式的调用session.save()(或session.persist()),或者在关联的映射文件中加入cascade="all"或cascade="save-update"(或cascade="persist")才能够自动关联执行。
21
net.sf.hibernate.QueryException: undefined alias: A[SELECT A,B FROM C where ]
net.sf.hibernate.hql.PathExpressionParser.token(PathExpressionParser.java:103)
net.sf.hibernate.hql.ParserHelper.parse(ParserHelper.java:29)
net.sf.hibernate.hql.SelectParser.token(SelectParser.java:170)
net.sf.hibernate.hql.ClauseParser.token(ClauseParser.java:87)
net.sf.hibernate.hql.ClauseParser.end(ClauseParser.java:114)
net.sf.hibernate.hql.PreprocessingParser.end(PreprocessingParser.java:143)
net.sf.hibernate.hql.ParserHelper.parse(ParserHelper.java:30)
net.sf.hibernate.hql.QueryTranslator.compile(QueryTranslator.java:149)
net.sf.hibernate.hql.QueryTranslator.compile(QueryTranslator.java:138)
net.sf.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:295)
net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1572)
net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1543)
net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:49)

项目中使用hibernate2,一次在拼HQL并执行查询的过程中出现了上面的异常

使用的HQL查询代码如下

String HOL = ''SELECT A,B FROM C WHERE ....";

Query query = session.createQuery(hql);
query.list();

HQL感觉没什么问题,但是执行查询却报了上面的异常,而且A,B,字段已经在配置在相应的.hbm.xml文件中,对应的表和JAVA bean类都没有问题,一直很疑惑,在网上搜索了好多相关资料,原来是由于HQL中表C没有使用别名,改用下面的HQL:

select d.A,d.B from C as d where ..

之后问题解决,原来这是HQL中的设置,即便是只对一张表进行查询,也必须使用别名,唉,开源的项目难免会有问题,报以宽容的态度吧,不知道这个问题是否在hibernate3的版本解决,说实话,不怎么灵活。

2、Could not find a getter for idifReturnFlag in。。。。

at net.sf.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:182)
at net.sf.hibernate.mapping.Property.getGetter(Property.java:175)
at net.sf.hibernate.persister.AbstractEntityPersister.<init>(AbstractEntityPersister.java:749)
at net.sf.hibernate.persister.EntityPersister.<init>(EntityPersister.java:690)
at net.sf.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:42)
at net.sf.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:137)

日前在使用hibernate过程中出现上面异常,但是在JAVA BEAN 中已经有对应的get方法经过查阅相关代码,发现问题是由于JAVA bean中get方法的设置导致的,由于hibernate在反射寻找对应的get或者set方法过程中做如下调用:

if( methodName.startsWith("get") ) {
String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
String testOldMethod = methodName.substring(3);
if( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) return methods[i];

}

其中会调用JAVA 内置的Introspector.decapitalize方法,具体代码如下

public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}

改方法是如果字符串的前两个字母都是大写字母,则直接返回改字符串,否则将改字符串的第一个字母置为对应的大写字母之后,返回

如果方法getXXX和setXXX中get和set之后的字符串经过上面的处理之后和原字符串有一个能与*.hbm.xml中对应的属性相同,则返回对应的方法,否则,返回空

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. Hibernate配置文件的位置和内容? Hibernate的配置文件名为hibernate.cfg.xml,一般放在src目录下。配置文件中包含了数据库连接信息、映射文件信息、缓存信息等。 2. Hibernate中如何进行事务操作? Hibernate的事务操作需要先开启事务,然后通过Session的操作完成数据库操作,最后提交或回滚事务。 3. Hibernate中如何进行对象关系映射? Hibernate通过XML配置文件或注解方式来进行对象关系映射。XML配置文件中需要指定对象与表的映射关系、属性与字段的映射关系等。 4. Hibernate中如何进行缓存管理? Hibernate提供了一级缓存和二级缓存。一级缓存是Session级别的缓存,二级缓存是SessionFactory级别的缓存。可以通过配置文件来启用二级缓存,并指定缓存策略。 5. Hibernate中如何进行延迟加载? Hibernate中可以通过在映射文件中指定lazy属性来进行延迟加载。当需要使用关联对象时才会进行加载,避免了一次性加载所有数据的开销。 6. Hibernate中的懒加载有哪些问题? Hibernate中的懒加载可能会导致N+1次查询问题,即在查询关联对象时需要执行多次查询,造成性能问题。可以通过Fetch策略来解决该问题。 7. Hibernate中如何进行SQL查询? Hibernate中可以通过Criteria API或HQL来进行SQL查询。其中Criteria API提供了面向对象的查询方式,HQL则提供了类似SQL的查询语言。 8. Hibernate中如何进行连接池配置? Hibernate中可以通过配置文件来配置连接池。可以指定连接池大小、最大等待时间、最大空闲时间等参数。 9. Hibernate中如何进行多表查询? Hibernate中可以通过Criteria API或HQL来进行多表查询。可以通过关联查询、子查询等方式来实现多表查询。 10. Hibernate中如何进行分页查询? Hibernate中可以通过Criteria API或HQL来进行分页查询。可以指定每页的记录数、当前页数等参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值