hibernate 一些bug的分析
来源:互联网 发布:电视机安卓软件 编辑:程序博客网 时间:2024/05/22 12:08
hibernate 错误分析
错误1:
代码:
Peopletable people=(Peopletable)session.load(Peopletable.class,"2");
在hibernate3.1版中报的错误是:
org.hibernate.exception.SQLGrammarException: could not insert: [net.gaoxin.Computertable]
在hibernate3.2.6中报的错误是:
Exception in thread "main" org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class
java.lang.Integer, got class java.lang.String
看来3.2版比3.1版更人性化,提示信息更明确。
解决:
Peopletable people=(Peopletable)session.load(Peopletable.class,new java.lang.Integer(2));
后面的参数类型换成Integer/int的就可以了。
看来后面一个变量的类型是int的。
错误2:
版本:hibernate-3.1
代码:
Peopletable people=(Peopletable)session.load(Peopletable.class,"2");
computer.setPeople(people);
session.save(computer);//错误行
错误:
Hibernate: insert into computertable (cmodel, people) values (?, ?) select scope_identity()
16:34:17,953 INFO IntegerType:89 - could not bind value '2' to parameter: 2
16:34:17,953 WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: 07009
16:34:17,984 ERROR JDBCExceptionReporter:72 - [Microsoft][SQLServer 2000 Driver for JDBC]Invalid parameter binding(s).
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [net.gaoxin.Computertable]
Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Invalid parameter binding(s).
解决:
更新hibernate的版本到3.2.6 ,会产生错误1,然后把错误一解决就可以了。hibernate的bug啊。
错误3:
版本hibernate-3.1
错误:
Exception in thread "main" org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned
before calling save(): net.gaoxin.Computertable
原因 是在hbm.xml的 <generator class="assigned"/>
解决:手动设置id。
错误4:
Invalid parameter binding(s).
16:43:10,078 ERROR AbstractFlushingEventListener:299 - Could not synchronize database state with session
原因:<generator class="assigned"/>
解决:<generator class="nativ"/>
总之:hibernate-3.1有bug还是要升级到3.2,bug应该会少些。
错误5:
11:24:27,613 ERROR JDBCExceptionReporter ORA-01747: invalid user.table.column, table.column, or column specification
11:24:27,613 ERROR AbstractFlushingEventListener Could not synchronize database state with session
原因:可能是使用了数据库的关键词
解决:该列的定义。
错误6:
org.hibernate.exception.GenericJDBCException: could not load an entity: [mypack.Customer#3]
原因:意思是不能加载这个实体,没有主键=3 的这条记录
问题7:按照夏昕的教程《Hibernate 开发指南 v1.0》
使用Middlegen-Hibernate-r5 配置sqlserver2000数据库,然后运行ant的话会产生如下错误:
No <table> elements specified. Reading all tables. This might take a while...
build failed.
这个是因为在mssql中的属性名schema,catalog不应该去掉,应该有内容,
在mssql.xml中内容如下:
<property name="database.schema" value="dbo"/>
<property name="database.catalog" value="pubs"/>
在 build.xml中内容如下:
schema="${database.schema}"
catalog="${database.catalog}"
注意在build.xml不要有空格。
错误8:
Peopletable people=(Peopletable)session.load(Peopletable.class,4);
这一句话应该是有错的啊,没有serializable =4的记录啊。是不是bug?但是报了下面的错误:
ERROR JDBCExceptionReporter:72 - [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]INSERT 语句与 COLUMN FOREIGN KEY
约束 'FK__computert__peopl__7A672E12' 冲突。该冲突发生于数据库 'pubs',表 'peopletable', column 'PID'。
没有主键的值=4的记录。
使用session.get可以解决上面的问题。
session.load()的调用过程使用了内部缓存和二级缓存,然后再从数据中读取。
而session.get()只使用了内部缓存,如果内部缓存没有数据将越过二级缓存,直接调用数据库读取数据。
因此load函数可能在二级缓存中发生了问题,在使用session.load的时候使用监视器,发现people的内容是
com.sun.jdi.InvocationException occurred invoking method.
people的值都是null,但是在代码中用 if(people!=null)做判断不是空。
printf的时候报错:No row with the given identifier
exists。说明你load了一个非代理对象或者是你load了一个代理对象但是后来又访问了这个对象。
说明我们在print的时候才读取到那个实体类,没有print的时候只是一个代理类,不为空也就可以接受。
错误9:
在报了错误8之后,我插入一个正确的记录,却发现在表中的主键的值应该是10的,现在是11了,也就是说刚才虽然由于错误8,提示没有成功
。但是那个独立的主键值还是生成了。
分析10:
目的:批量插入数据
Transaction t=session.beginTransaction();
Peopletable people=new Peopletable();
int seed=100;
for(int i=0;i<seed;i++){
people.setPname(String.valueOf(new java.util.Random().nextInt(seed)));
session.save(people);
session.flush();
t.commit(); //没有办法批量处理
}
结果:Transaction not successfully
started,但是在数据库中插入了一条记录,这个不是我们想要的结果。百度了一下,发现是事务的原因。
将Transaction t=session.beginTransaction();
发到for循环中;没有报错,但是显示用事件查看器发现只插入了一条,其余执行update操作。
考虑批量处理有问题。百度之。
分析:首先程序有问题,在上面的过程中只创建了一个peopletable对象。每次都是更改那个对象中的值,这个是hibernate机理的作用,在
cache应该有缓存,而people对象现在是属于persistent状态,因此每次的save和submit都做update操作。
因此需要重新创建对象才会有用。
修改后的代码:
Transaction t=session.beginTransaction();
int seed=100;
for(int i=0;i<seed;i++){
Peopletable people=new Peopletable();
people.setPname(String.valueOf(new java.util.Random().nextInt(seed)));
session.save(people);
}
t.commit();
现在ok了。
但是可能在数据量大的时候,数据处理很慢。如果启用了second level cache的话,对批处理不利,因为每次执行insert/update操作,
hibernate在transaction后不得不通告second level cache缓存这个记录,造成很慢,因此在batch操作的时候要禁用cache,
并且每隔一批记录要执行session.flush()和clear()。
一般数据是放在session中,只有在显式执行session.flush();或transaction.commit();操作之后才将数据保存到数据库中。
一级缓存:session实例维护 ,内部缓存
二级缓存:SessionFactory
如果我们只想获取表中记录的一个字段,我们可以使用延迟加载的方式,即设置表对应的类的加载方式lazy="true".
<class name="Computertable" table="computertable" lazy="true" >
Computertable computer=(Computertable)session.load(Computertable.class, new Integer(2));
通过查看computertable的内存快照,我们可以发现computertable的属性都是null。
原理是:hibernate的代理机制load的加载方式是通过代理类实现的。
错误1:
代码:
Peopletable people=(Peopletable)session.load(Peopletable.class,"2");
在hibernate3.1版中报的错误是:
org.hibernate.exception.SQLGrammarException: could not insert: [net.gaoxin.Computertable]
在hibernate3.2.6中报的错误是:
Exception in thread "main" org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class
java.lang.Integer, got class java.lang.String
看来3.2版比3.1版更人性化,提示信息更明确。
解决:
Peopletable people=(Peopletable)session.load(Peopletable.class,new java.lang.Integer(2));
后面的参数类型换成Integer/int的就可以了。
看来后面一个变量的类型是int的。
错误2:
版本:hibernate-3.1
代码:
Peopletable people=(Peopletable)session.load(Peopletable.class,"2");
computer.setPeople(people);
session.save(computer);//错误行
错误:
Hibernate: insert into computertable (cmodel, people) values (?, ?) select scope_identity()
16:34:17,953 INFO IntegerType:89 - could not bind value '2' to parameter: 2
16:34:17,953 WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: 07009
16:34:17,984 ERROR JDBCExceptionReporter:72 - [Microsoft][SQLServer 2000 Driver for JDBC]Invalid parameter binding(s).
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [net.gaoxin.Computertable]
Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Invalid parameter binding(s).
解决:
更新hibernate的版本到3.2.6 ,会产生错误1,然后把错误一解决就可以了。hibernate的bug啊。
错误3:
版本hibernate-3.1
错误:
Exception in thread "main" org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned
before calling save(): net.gaoxin.Computertable
原因 是在hbm.xml的 <generator class="assigned"/>
解决:手动设置id。
错误4:
Invalid parameter binding(s).
16:43:10,078 ERROR AbstractFlushingEventListener:299 - Could not synchronize database state with session
原因:<generator class="assigned"/>
解决:<generator class="nativ"/>
总之:hibernate-3.1有bug还是要升级到3.2,bug应该会少些。
错误5:
11:24:27,613 ERROR JDBCExceptionReporter ORA-01747: invalid user.table.column, table.column, or column specification
11:24:27,613 ERROR AbstractFlushingEventListener Could not synchronize database state with session
原因:可能是使用了数据库的关键词
解决:该列的定义。
错误6:
org.hibernate.exception.GenericJDBCException: could not load an entity: [mypack.Customer#3]
原因:意思是不能加载这个实体,没有主键=3 的这条记录
问题7:按照夏昕的教程《Hibernate 开发指南 v1.0》
使用Middlegen-Hibernate-r5 配置sqlserver2000数据库,然后运行ant的话会产生如下错误:
No <table> elements specified. Reading all tables. This might take a while...
build failed.
这个是因为在mssql中的属性名schema,catalog不应该去掉,应该有内容,
在mssql.xml中内容如下:
<property name="database.schema" value="dbo"/>
<property name="database.catalog" value="pubs"/>
在 build.xml中内容如下:
schema="${database.schema}"
catalog="${database.catalog}"
注意在build.xml不要有空格。
错误8:
Peopletable people=(Peopletable)session.load(Peopletable.class,4);
这一句话应该是有错的啊,没有serializable =4的记录啊。是不是bug?但是报了下面的错误:
ERROR JDBCExceptionReporter:72 - [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]INSERT 语句与 COLUMN FOREIGN KEY
约束 'FK__computert__peopl__7A672E12' 冲突。该冲突发生于数据库 'pubs',表 'peopletable', column 'PID'。
没有主键的值=4的记录。
使用session.get可以解决上面的问题。
session.load()的调用过程使用了内部缓存和二级缓存,然后再从数据中读取。
而session.get()只使用了内部缓存,如果内部缓存没有数据将越过二级缓存,直接调用数据库读取数据。
因此load函数可能在二级缓存中发生了问题,在使用session.load的时候使用监视器,发现people的内容是
com.sun.jdi.InvocationException occurred invoking method.
people的值都是null,但是在代码中用 if(people!=null)做判断不是空。
printf的时候报错:No row with the given identifier
exists。说明你load了一个非代理对象或者是你load了一个代理对象但是后来又访问了这个对象。
说明我们在print的时候才读取到那个实体类,没有print的时候只是一个代理类,不为空也就可以接受。
错误9:
在报了错误8之后,我插入一个正确的记录,却发现在表中的主键的值应该是10的,现在是11了,也就是说刚才虽然由于错误8,提示没有成功
。但是那个独立的主键值还是生成了。
分析10:
目的:批量插入数据
Transaction t=session.beginTransaction();
Peopletable people=new Peopletable();
int seed=100;
for(int i=0;i<seed;i++){
people.setPname(String.valueOf(new java.util.Random().nextInt(seed)));
session.save(people);
session.flush();
t.commit(); //没有办法批量处理
}
结果:Transaction not successfully
started,但是在数据库中插入了一条记录,这个不是我们想要的结果。百度了一下,发现是事务的原因。
将Transaction t=session.beginTransaction();
发到for循环中;没有报错,但是显示用事件查看器发现只插入了一条,其余执行update操作。
考虑批量处理有问题。百度之。
分析:首先程序有问题,在上面的过程中只创建了一个peopletable对象。每次都是更改那个对象中的值,这个是hibernate机理的作用,在
cache应该有缓存,而people对象现在是属于persistent状态,因此每次的save和submit都做update操作。
因此需要重新创建对象才会有用。
修改后的代码:
Transaction t=session.beginTransaction();
int seed=100;
for(int i=0;i<seed;i++){
Peopletable people=new Peopletable();
people.setPname(String.valueOf(new java.util.Random().nextInt(seed)));
session.save(people);
}
t.commit();
现在ok了。
但是可能在数据量大的时候,数据处理很慢。如果启用了second level cache的话,对批处理不利,因为每次执行insert/update操作,
hibernate在transaction后不得不通告second level cache缓存这个记录,造成很慢,因此在batch操作的时候要禁用cache,
并且每隔一批记录要执行session.flush()和clear()。
一般数据是放在session中,只有在显式执行session.flush();或transaction.commit();操作之后才将数据保存到数据库中。
一级缓存:session实例维护 ,内部缓存
二级缓存:SessionFactory
如果我们只想获取表中记录的一个字段,我们可以使用延迟加载的方式,即设置表对应的类的加载方式lazy="true".
<class name="Computertable" table="computertable" lazy="true" >
Computertable computer=(Computertable)session.load(Computertable.class, new Integer(2));
通过查看computertable的内存快照,我们可以发现computertable的属性都是null。
原理是:hibernate的代理机制load的加载方式是通过代理类实现的。
- hibernate 一些bug的分析
- JSF+Spring+Hibernate 的一些Bug
- 说说分析bug的一些心得
- 关于bug分析与异常处理的一些思考
- 关于bug分析与异常处理的一些思考
- hibernate的bug
- hibernate的小bug
- 整理的一些Bug
- Delphi的一些Bug
- duilib的一些bug
- CSS的一些Bug
- 常见的一些bug
- hibernate 分页查询的bug
- Hibernate的bug之别名
- BUG管理的一些方法
- ORACLE HINT 的一些BUG
- Android系统的一些bug
- QQ邮箱的一些bug
- RATIONAL
- 基于线周期累加法的ADE7758校准系统的设计
- 创业公司10条成功准则
- python编码问题
- 转载的技术文章
- hibernate 一些bug的分析
- websphere
- 一个系统的安全认证过程
- ajax webservice applet
- 在页面加载的时候,滚动条自动滚到最下面的解决方案
- 依附适合自己的先进技术,少走弯路
- 近期生活
- Java基础知识的分析
- 从校园走进社会