追随Java
简单的事情重复做,就会产生累积效应!
posts - 260,  comments - 338,  trackbacks - 0
  用hibernate作为持久层,update是出现了重复记录。奇怪了,为什么会明明是update,怎么可能出现添加一条记录的结果呢?
由于在操作过程中,修改了某个属性(字段),可以update成功。但我在页面中的另一个属性(它有一个回车操作去从数据库拿另外的数据来更新)中修改,就会出现添加一个新的记录。WHY?   
  我仔细看了一下日志,两个不同的操作sql真不一样,一个是用insert,另一个是用update语句。反过来的想了想有关pojo相等的比较原理。
  我于是有了几个想法,来测试。
  1)两个对象的比较(equals)规则的可能出错了。
    在我记忆中,pojo对象默认的equals方法是用主键来认识,两个对象是否相等。以前没有重写equlas方法和hashCode方法。对于不是很熟悉hibernate的我来说,还是决定重写这两个方法。编译完,重启tomcate,问题依旧。
        2) 是不是我在持久层调用方法出错了呢?
   仔细看了一下saveOrUpdate()这个方法的文档。saveOrUpdate方法能通过现个对象的equals方法来区分,到底是要insert还是要update。看来这个应该没有问题。
  3)经过上面两步的推理。难道是要修改对象的关键字的值被漏掉了吗?
   我追踪了主鍵值,由于主键值在页面是在一个隐藏域。当操作出错属性(它有一个回车操作去从数据库拿另外的数据来更新)返回时,查看了页面的源代码,果然,隐藏域的值为空。原来在我返回页面时,忘记给它保存原来的值了。
  经过一番折腾,终于搞定了。:)
  在编码过程中一定要仔细,严谨,平时多注意理论知识的积累,理论联系实践。
   

    

     
posted on 2005-09-07 14:22 Harryson 阅读(6174) 评论(5)  编辑  收藏 所属分类: Hibernate

FeedBack:
# re: 用hibernate作为持久层,update是出现了重复记录
2005-09-07 20:05 | Water Ye@ITO
在hibernate, 这是不可能发生的, 贴代码出来看看

update的po不是get或load出来的吧, 如果是new出来的, setId就没事了

在开发最好show_sql="true", 这样就不用也hibernate骗了  回复  更多评论
  
# re: 用hibernate作为持久层,update是出现了重复记录
2005-09-07 22:30 | Harryson
  谢谢,Water Ye的回答和宝贵建议。
是这样子的我保存数据和更新数据都是在同一个方法中。用的是spring+hibernate的dao implements HibernateDaoSupport在保存的时候就调用了
TjobsheetFinishTemp tft = new TjobsheetFinishTemp();
tft.set**();
...
getHibernateTemplate().saveOrUpdate(tft);//它用tft(pojo)对象的equals来判断两个对象是否一致。
可在set**()主鍵的时候没有注意到在另一个操作时,主键值在页面中用javascript处理时给忘记了,:)所以hibernate在处理时,就认为它们是不同的对象。:(

  回复  更多评论
  
# re: 用hibernate作为持久层,update是出现了重复记录
2005-09-07 22:39 | Water Ye@ITO
id == null时, hb认为是新建一条记录

对于简单的crud, 保存数据和更新数据在dao中可以为同一个方法

但对一些复杂的业务处理(单据的修改), 如果没有service层的话, 最好分开  回复  更多评论
  
# re: 用hibernate作为持久层,update是出现了重复记录
2005-09-07 23:08 | Harryson
我现在觉得也是。现在我就感觉到了这一点。因为我现在保存数据有时会出错,现在正在找原因,郁闷了一下午了。:<
出错信息如下:
java.lang.ArrayIndexOutOfBoundsException//数组越界?
at java.lang.System.arraycopy(Native Method)
at com.microsoft.jdbc.sqlserver.tds.TDSRPCParameter.write(Unknown Source
)
at $Proxy5.addShipment(Unknown Source)//我在action(control)中调用了DAO中的方法,Unknown Source不知是为会什么?因为在action的类中我用了一个这样一方法,shipmentDAO.addShipment(this),this代表了本身的对象,用来(获取)传送页面请求的数据到DAO中。不知前辈们是怎么处理这个地方的?
at com.legend.shipment.web.Shipment2Action.saveShipment(Shipment2Action.
java:196)//这个出错的类的方法出错的语句, shipmentDAO.addShipment(this);

还有就是:
org.springframework.transaction.TransactionSystemException: Could not roll back
Hibernate transaction; nested exception is org.hibernate.TransactionException: J
DBC rollback failed
org.hibernate.TransactionException: JDBC rollback failed
WARN - DefaultActionInvocation.executeResult(260) | No result defined for action
com.legend.shipment.web.Shipment2Action and result null

下面这个不知会不会有问题出现呢?
at com.legend.shipment.dao.hibernate.ShipmentDAOHibernate.generateShipNu
m(ShipmentDAOHibernate.java:198)
//Query query = session.createQuery(sql);
// query.setLong("jftJsId",jsoId.longValue());它们有可能会出现上面出现的错误吗?  回复  更多评论
  
# re: 用hibernate作为持久层,update是出现了重复记录
2005-09-08 15:26 | Harryson
  问题怎样得以解决了,晕了差不多一天。java.lang.ArrayIndexOutOfBoundsException//数组越界? 都是它惹的祸。因在程序中我是引用了了一个数组,但也不至于会出差吧,:(。那么问题到在那呢?是这样的,在我第系统中要访问两个不同的数据库,一个是当前开发的系统的数据库,另一个是用来攻取某些数据。我只把第一个数据库用spring+hibernate来管理,另一个用jdbc业处理。“org.springframework.transaction.TransactionSystemException: Could not roll back
Hibernate transaction; nested exception is org.hibernate.TransactionException: J
DBC rollback failed
org.hibernate.TransactionException: JDBC rollback failed
WARN - DefaultActionInvocation.executeResult(260) | No result defined for action
com.legend.shipment.web.Shipment2Action and result null
”从这个看来,我猜想是不是不能在DAO中引用另一个数据库的Connection,这样会造成spring事务管理的混乱。于是我就改写。把用jdbc处理的东东,也采用spring+hibernate的模式。问题依旧。这可就晕了,眼看系统就要上线了。到了关键时候怎么出问题呢?心里有点紧张,一丝不安。一直有信心把问题解决。没有办法了,我只得在整个程序中添加了很多log.debug()来测试。测试出,当我不用另一个(获取数据的数据库)时,问题就不会产生,只要一加上就会产生上述问题。这可就奇怪了。还有就是有些数据可以,有数据数据不可以。那么问题应该出错在数据据格式(转化)上。我把要从获取数据库的数据手动硬写在程序中,程序通过。我原来从数据库获取的数据仔细看过。原来,数据库的数据为81.6的数据输出来的时候变成了81.599999999999994315658113919198513031005859375。这样我就想是不是就会产生数组溢出呢?原后我就把数据改成81.6这样子就没有问题了。让我们仔细看一下源码
sql = "select b.labourCost,b.epibolyCost from TworkCost as b where b.jscostId = :jscostId";
session = getSession();
query = session.createQuery(sql);
query.setInteger("jscostId",jscostId.intValue());
list = query.list();
iterator = list.iterator();
Object[] rows = null;
while(iterator.hasNext()) {
rows= (Object[]) iterator.next();
// System.out.println((BigDecimal)rows[0]+" "+rows[1]);
}
"rows"数组中的内容是BigDecimal的,我可把它强制转换成了double型的,就在这个转换过程中,小数位增加了很多,当添加到数据库中时就发出了数组溢出的error!
所以,搞技术工作的一定要严谨,细心
  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

<2005年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

常用链接

留言簿(10)

随笔分类(319)

AJAX

Coffee House

CSS

Java

JavaScript

Open Source

ProjectManagement

友情Blog

最新随笔

最新评论

阅读排行榜

评论排行榜