【问题标题】:Hibernate save is doing update休眠保存正在更新
【发布时间】:2016-01-14 02:35:14
【问题描述】:

我正在处理一个需要向表中插入新审计记录的项目。 (例如 new_vale vs old_value),有几个需要更新的字段。

我正在尝试解决的问题:

session.save() 不是执行 "INSERT" 而是执行 "UPDATE"

    private void updateCollabPoApprovaForASN(CollabPoApprovalKey key, PurchaseOrderUpdateASN updateAsn){
       CollabPoApproval collabPoApproval  = this.collabPoApprovalGateway.findById(key);

       compareAndSetChangedValue(updateAsn, collabPoApproval);
       key.setChangeId(generateId());
       collabPoApproval.setKey(key);

       this.collabPoApprovalGateway.save(collabPoApproval);

}

基本上,我所做的是,我使用休眠查询来获取现有记录,然后通过手动设置 ID 修改主键并更新这几个审计字段。最后,将其保存回数据库。

SQL 生成:

update CollabPoApproval set OLD_DRAWING_NUMBER=?, NEW_DRAWING_NUMBER=? ... where ID=? and SU_ID=? and PO=? and LINE=?

表格背景

ID不是自增字段,是手动生成的ID,基本上是TimeStamp+[0-999]的组合(比如20150412113637011),所以我必须手动设置,然后再保存。
该表的主键是包括ID在内的4个字段的组合,它们都是整数。除此之外,它还包括其他几十个我只关心的审计字段。

我尝试过但不起作用的方法:

Google/StackOverFlow 搜索并尝试了不同的方法。

第一
添加以下生成器(我相信这是默认的):

<generator class="assigned" />

所以 hbm composit-id 如下所示:

<composite-id class="CollabPoApprovalKey" name="key">
    <key-property name="Id" column="ID" type="long" />
    <key-property name="suId" column="SU_ID" type="integer" />
    <key-property name="po" column="PO" type="integer" />
    <key-property name="line" column="LINE" type="short" />
    <generator class="assigned" />
</composite-id>

第二次

尝试使用此方法save(String entityName, Object object) by

this.collabPoApprovalGateway.save("CollabPoApproval",CollabPoApproval)

不工作

第三次

Trid 使用这个方法saveOrUpdate(Object object)

还是不行。

【问题讨论】:

    标签: java sql-server hibernate persistence


    【解决方案1】:

    如果要插入新记录,则创建类型为 CollabPoApproval 的新对象并从选定对象复制值而不是修改它。 Hibernate 会查看对象的引用,在这种情况下,引用并没有改变它触发更新语句而不是插入的原因。

    CollabPoApproval collabPoApproval  = this.collabPoApprovalGateway.findById(key);
    CollabPoApproval collabPoApprovalNew = new CollabPoApproval ();
    //copy collabPoApproval values to collabPoApprovalNew 
    //do other modification
    this.collabPoApprovalGateway.save(collabPoApprovalNew );
    

    【讨论】:

    • 谢谢 Prera​​k,这解决了我的问题。我的同事建议的另一种方法是将 evict() 称为会话中的现有记录。 (还没有机会尝试),我认为它会起作用。
    • 是的..但这会使您的代码不必要地复杂化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2011-09-20
    • 2012-08-09
    • 2013-06-09
    • 2014-06-10
    • 2011-11-06
    相关资源
    最近更新 更多