IT博客百科

广告

文章

hibernate常见错误汇总

2013-10-12 15:15:50 本文行家:IT_Kai

1.插入失败,某一字段没有默认值:insertfail;fileddepiddoesn'thaveadefaultvalue这个错误往往是你丈二和尚—摸不着头脑,因为它并没有提示哪一行错误,也没说清为什么错误;笔者经过层层排错找出了错误:这是数据库中的错误,说depid字段没有默认值是因为建表的时候depid不允许为空,而你在save()的时候往往都是先不插入外键的,只在commit()的时候h

1. 插入失败,某一字段没有默认值:insert fail;filed depid doesn't have a default value

这个错误往往是你丈二和尚—摸不着头脑,因为它并没有提示哪一行错误,也没说清为什么错误;笔者经过层层排错找出了错误:这是数据库中的错误,说depid字段没有默认值是因为建表的时候depid不允许为空,而你在save()的时候往往都是先不插入外键的,只在commit()的时候hibernate后台会执行一句updatesql语句更新进去外键。所以让他允许为空就ok了。

2. myeclipse中没有报错,但是就是数据库中楞写不进去数据,这是原因呢?

原因一:你的配置文件中少了一映射的语句,即hibernate.cfg.xml中少了一句<mapping resource="com/hbsi/one2many/Employee.hbm.xml"/>;没有这句话则无法映射到数据库。

原因二:还是配置文件中的错,以下这些语句一定要写对,错一不可

<propertyname="dialect">

org.hibernate.dialect.MySQLDialect</property>

<property name="connection.url">

jdbc:mysql://localhost:3306/hibernate</property>

<property name="connection.username">root</property>

<property name="connection.password">root</property>

<property name="connection.driver_class">

com.mysql.jdbc.Driver</property>

尤其是方言那条语句,即dialect中的数据库一定要对应,如果你用的是mysql语句一定要用mysql的方言, org.hibernate.dialect.MySQLDialect是总概述,也有不同版本对应的方言,如果你标上了数据库的版本号则要写对应版本号的mysql数据库;这里容易犯错的就是一般配置文件都是从模版文件中拷来然后修改的,而模版文件中一般方言会是hsql,就是hibernate自带的,如果这么写可以映射到mysql数据库,但是会有一些错误,比如你是时间类型,这种类型可以分日期date、时间time、日期时间datetmie三种类型,数据库类型分别对应类中不同类型,这时写数属性property的时候就要指明type类型,但是用hsql即使指明了也不起作用,而且你指明create表而不是更新表也不起作用。

3. 测试的时候出错,并值提示一句话:空指针nullPointException

这种错误也很让人纠结,控制台报了好多错,但是都不是一目了然的,报的错也许你检查好久怎么都是对的,但是愣说那几句有错,原因也有很多。

原因一:这种是不是错误的错误;为什么这么说呢!?这种错误常见于查询方法,尤其是根据id查询的方法,比如你数据库中没有你要查询的id就会出现空指针异常。

原因二:配置文件中的属性标签写错,<property name="show_sql">true</property>;这里标签为property,但是写多properties,手一哆嗦就容易写成后者,所以如果出现这样的错你不妨去看看这个文件是写错了,这个粗就是个指东打西的错,控制台不会清楚的给你指出是什么错,只会告诉说某个类属性找不到或无法对应更甚者,其他的属性值都对了,数据库与之对应的也对就是唯独某一个属性没有插进数据库,这时就有可能是property这个标签的错误了,可以看看是否粗心写错了。

原因三:具体请看下面这个按id查询的模版方法:

publicvoid find(){

try{

session = HibernateUtil.getSession();

Customer cus = (Customer)session.get(Customer.class,4);

Set<Orders> ord = cus.getOrd();

System.out.println(ord.size());

}catch(Exception e){

e.printStackTrace();

}finally{

HibernateUtil.close();

}

}

该方法中,session = HibernateUtil.getSession();这句尤为重要,如果这句忘了写,或被你忽视了,那你就等着空指针找你吧!

原因四:配置文件中的mapping标签错误

问题出多出在你做测试的时候,比如你测试一对一关系表的基于外键和基于主键的操作测试的时候,你可能会建两个包,一个用来测试基于外键的,一个用来基于主键的;这时里面的类都是一样的,只是包不同,你在hibernate.cfg.xml配置文件中配置的时候会出现两个不同包中的xxx.hbm.xml文件。比以下这种情况:

<!--

<mapping resource="com/hbsi/many2one/Employee.hbm.xml"/>

<mapping resource="com/hbsi/many2one/Department.hbm.xml"/>

-->

<mappingresource="com/hbsi/one2many/Employee.hbm.xml"/>

<mappingresource="com/hbsi/one2many/Department.hbm.xml"/>

请尊重别人的劳动成果,转载请指明:http://blog.csdn.net/tianyazaiheruan

4 .常见的Unknown entity错

一般出现这种错,一般都是映射错误,有可能是配置文件中的,有可能是类对应的映射文件中的。

(1).Unknown entity: java.util.HashSet问题

主要是以下问题,下面代码是错误的代码:

Customer cus =new Customer();

Set<Orders> ord =new HashSet<Orders>();

Orders order1 =new Orders();

Orders order2 =new Orders();

cus.setOrd(ord);

session.save(ord); //这里方法中传入的是ord

session.save(order1);

session.save(order2);

正确的代码

Customer cus =new Customer();

Set<Orders> ord =new HashSet<Orders>();

Orders order1 =new Orders();

Orders order2 =new Orders();

cus.setOrd(cus); //应该传入的是cus

session.save(ord);

session.save(order1);

session.save(order2);

(2) Unknownentity:com.entity.TestEntity问题

排出这个错误

1)看看entity中,不能为空的属性,有没有set();

2)在META-INF persistence.xml,有没有声明你的entity

最后发现自己,在persistence.xml没有加下面这句导致了Jpa Unknown entity:

1. <class>com.entity.TestEntity</class>

persistence.xml

1. <?xmlversion="1.0"encoding="UTF-8"?>2. <persistenceversion="1.0"xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">3. <persistence-unitname="JpaTest"transaction-type="RESOURCE_LOCAL">4. <provider>org.hibernate.ejb.HibernatePersistence</provider>5. <class>com.entity.TestEntity</class>6. <exclude-unlisted-classes>true</exclude-unlisted-classes>7. <properties>8. <propertyname="hibernate.connection.driver_class"value="oracle.jdbc.driver.OracleDriver"/>9. <propertyname="hibernate.connection.url"value="jdbc:oracle:thin:@localhost:1521:orcl"/>10. <propertyname="hibernate.connection.username"value="ningnian"/>11. <propertyname="hibernate.connection.password"value="ningningx"/>12. <propertyname="hibernate.dialect"value="org.hibernate.dialect.Oracle10gDialect"/>13. <propertyname="hibernate.show_sql"value="true"/>14. <propertyname="hibernate.hbm2ddl.auto"value="update"/>15. </properties>16. </persistence-unit>17. </persistence>

(3) Unknown entity: java.lang.Object问题

错误日志:

严重: Servlet.service() for servlet spring3 threw exception
org.hibernate.MappingException: Unknown entity: java.lang.Object

代码:

IvceConfigInfo ivceConfigInfo = getConfigInfoByKey(id); //通过主键查询到需要更新的数据

ivceConfigInfo.setInitName(key); // 设置更新的值
ivceConfigInfo.setValue(value); // 设置更新的值
this.update(ivceConfigInfo); // 此句发生上述错误

改为 this.update("IvceConfigInfo", ivceConfigInfo); 即可

(4)Unknown entity: java.lang.String和java.lang.Integer问题

解决办法:删除也要指定其字段

public void delete(int id) {
Session session=HibernateUtil.getSession();
session.beginTransaction();
//session.delete(id); 错误代码的根源
String hql = "DELETE Admin WHERE id=?";
Query q = session.createQuery(hql);
q.setInteger(0, id);
q.executeUpdate();
session.getTransaction().commit();
HibernateUtil.closeSession(session);
}

public void delete(String userName) {
Session session=HibernateUtil.getSession();
session.beginTransaction();

String hql = "DELETE Admin WHERE userName=?";
Query q = session.createQuery(hql);
q.setString(0, userName);
q.executeUpdate();
session.getTransaction().commit();
HibernateUtil.closeSession(session);
}

处理异常多了发现其实只要看其主要的提示代码,还是可以找到原因的,特别是细节问题...今天就遇到了一个什么HibernateUtil类没有初始化的,找到其具体原因,其实就是一个数据库表中的较长的字段属性名给写错了,弄的报错说找不到该属性的get()、set()方法,刚开始还以为根本没错呢...

5. xxx.hbm.xml中错误

Must specify an identifier type id的唯一性,xxx.hbm.xml中id没有给他写名字;

determine entity name xxx.hbm.xml中class没有写名字,会报错找不到实体类

请尊重别人的劳动成果,转载请指明:http://blog.csdn.net/tianyazaiheruan

6. 级联操作时的错误

object references an unsaved transient instance - save the transient instance before flushing: com.hbsi.orders_o2mboth.Customer(对象引用一个未保存的瞬态实例——保存瞬时实例之前,冲洗:com.hbsi.orders_o2mboth.Customer);出现这种错,多出在双向级联表中,是因为你级联操作时出的错,比如你让单方放弃了操作inverse=”true”,又让单方进行级联操作 cascade=”save-update”;因为你让它放弃了操作,这时你在用增删改或者测试的时候就会把相应单方的代码省去,也应该省去,这时这些代码其实没有起作用,就是无用的代码。如以下:

/*Set<Orders> ords = new HashSet<Orders>();

ords.add(ord1);

ords.add(ord2);

session.save(cus);*/

但是问题就出现了,你不写单方操作的代码但是级联操作又放在多方操作的xxx.hbm.xml中(单方没有放的情况下),肯定会出错了,相当于没有想数据库插入单方数据。这时你要避免这样的错误,可以把级联操作的代码放到多方的xxx.hbm.xml中:<many-to-one name="cus" column="cid" cascade="save-update"/>

7. 不是错误的错

有时候报错:什么关闭时异常,说这句错误HibernateUtil.close();(注:这里的hibernateUtil方法是自己编写的util工具,不一定特指这个类,一般都是myeclipse自动生成的util工具类)这时不是util类里的错,可能是你try语句中引用的代码出错了,只是这句close()在finally里,所以不管对与错它都执行的原因,这时找错可以忽略这句,就是说可以先注释掉这句,再依次找错。

8. Could not execute JDBC batch update

不能执行jdbc数据库的批量更新。这个错误的解决方法:

在多方设置级联操作的同时,把单方的级联操作去掉,并且把多方那边的inverse=“true”也去掉,这时你操作出来的数据是删除多方数据的某一条的同时把单方级联的数据也删除,并且把多方剩下与单方级联的外键数据设置为空

9. attribute "cascade" must be declared for element type for "one-to-many"

翻译过来是:属性“cascade”必须被声明为元素类型为“一对多”,这个错误的原因是:我爸级联操作和放弃操作inverse="true" cascade="save-update"放在了<one-to-many class="Orders"/>这个标签属性上。

错误修改:正确的完整格式应该是:

<setname="ord"inverse="true"cascade="save-update">

<keycolumn="cid"/>

<one-to-manyclass="Orders"/>

</set>

10.Unable to resolve property:idCard

无法解决的属性:idCard

错误分析:IdCard.hbm.xml映射文件中出错,<one-to-one name="IdCard" cascade="save-update"/>;name属性值错误,name的取值都是某个类的属性值,所以应该是idCard

请尊重别人的劳动成果,转载请指明:http://blog.csdn.net/tianyazaiheruan

11.傻瓜式错误

注意包名和类名,映射文件和配置文件中的一定要和现实中的额、一样,不一样会找不到,提示找不到的错误的时候,你就可以朝着是不是包名或类名写错了或是不一样。尤其是下面这些位置的:

<hibernate-mapping package="com.hbsi.many2many">

<class name="Course" table="course">

<mappingresource="com/hbsi/many2many/Student.hbm.xml"/>

<mappingresource="com/hbsi/many2many/Course.hbm.xml"/>

<setname="course"table="student_course"cascade="save-update">

<keycolumn="student_id"/>

<many-to-manycolumn="course_id"class="Course"/>

</set>

12. Duplicate collection role mapping com.hbsi.many2manyboth.Student.course和

Attribute "Class" must be declared for element type "many-to-many".这个错一般同时出现,主要原因是后者引起的。Many-to-many没有Class这样的属性,,这里的错误的原因是,小写的class在many-to-many等这样的元素中是类型属性,但是如果误写成大写的就会出错

错误写法:

<many-to-many Class="Student" column="student_id"/>

正确写法:

<many-to-many class="Student" column="student_id"/>

13.duplicate entry 2-2 for key prymary

主键重复,这个错误多发在多对多的关系中,这是因为你两边同时维护,有没有让其中一方放弃维护,这是中间表会重复插入外键,因为一般中间表的两个外键又是它的主键,这时就会出现主键重复的情况,一方放弃维护即可解决问题。

14.Attribute "inverse" must be declared for element type "many-to-one".

属性“反向”必须被声明为元素类型“多对一”。如果你在多方设置了反转,即让多方放弃了维护,那么你在测试的时候就不能用多方来调用测试,否则会出现上面的错误。

15.Attribute "cloumn" must be declared for element type "element".

属性“cloumn”必须被声明为元素类型“元素”。这是什么错呢!?其实很简单,就是这句话<element type="string" cloumn="hobbies_name" not-null="true"/>;element标签的column属性写错了。

请尊重别人的劳动成果,转载请指明:http://blog.csdn.net/tianyazaiheruan

16.The content of element type "list" must match "(meta*,subselect?,cache?,synchronize*,comment?,key,(index|list-index),(element|one-to-many|many-to-many|composite-element|many-to-any),loader?,sql-insert?,sql-update?,sql-delete?,sql-delete-all?,filter*)".

出现这一堆错误的时候,是因为你用的是list高级映射,但是你没有写<list-index column="position"/>,这里是为表产生一个唯一位置标识符。这里list标签所特有的子标签,不写会报错。

18. class com.hbsi.component.Ablum not found while looking for property: id

映射文件出错。<class name="Album" table="ablum">;这里的类型属性name的值写错的缘故。所以一定要细心,尤其用到自己不熟悉的英语单词的时候一定要细心,如果怕出错就在多处用到的同一个单词都从一个正确的位置复制一下。

19.The content of element type "union-subclass" must match "(meta*,subselect?,synchronize*,comment?,tuplizer*,(property|many-to-one|one-to-one|component|dynamic-component|properties|any|map|set|list|bag|idbag|array|primitive-array)*,union-subclass*,loader?,sql-insert?,sql-update?,sql-delete?,resultset*,(query|sql-query)*)".

元素类型的内容“union”必须匹配;union-subclass标签的子标签与joined-subclass不一样,前者没有key子标签,后者有,这个错是因为画蛇添足,多了个key子标签。

错误:<union-subclassname="Skiller"table="skiller">

<keycolumn="emp_id"/>

<propertyname="skill"/>

</union-subclass>

正确:<union-subclassname="Skiller"table="skiller">

<propertyname="skill"/>

</union-subclass>

20.Cannot use identity column key generation with <union-subclass> mapping for: com.hbsi.extend.Employee

Id类型不对,这种错多出在继承映射中;而且是每个具体类一张表的情况 ;id的类型必须是hilo的(hilo在其他博文中有介绍,感兴趣的可以去看看),否则就会出上面的错。

<idname="empId">

<generatorclass="hilo"/>

</id>

21.Attribute "table" must be declared for element type "subclass".

属性“表”必须被声明为元素类型”子类”。这个问题多出在混合使用“一个类继承体系一张表”和“每个子类一张表” (映射文件)这种类型的映射中。请看下面的错误语句:

<subclassname="Skiller"table="skiller">

<propertyname="skill"/>

</subclass>

正确的语句是:

<subclassname="Skiller">

<propertyname="skill"/>

</subclass>

这是因为这种混合表的使用就是要使某一个子类与父类在同一个表中,而上面的错误语句却标明了table="skiller",这不是背道而驰么。

 

分享:
标签: hibernate 错误总结 java 杨凯专属频道 itblog | 收藏