是否有可能有条件地更新Hibernate 3中的列?

时间:2013-08-14 13:51:18

标签: java hibernate

我的方案是我有两个不同的API更新数据库表,一个我们将调用内部,另一个外部调用,其中一个是使用陈旧数据覆盖值。

通过Hibernate更新的数据当时在应用程序的内存中。如果外部源在内部应用程序中仍然在内存中时更新列(statusCd),则在内部应用程序中保存它的那一分钟,该值将被过时数据覆盖。

现在我意识到还有很多方法可以解决这个问题,但是我们已经确定将此对象的Hibernate代码修复限制为风险最小,只要有可能通过Hibernate这样做。

所以我有两个问题:

  1. 是否可以通过Hibernate说“是的,请在创建时将此值插入此列,但是,除非值为”取消“,否则请不要在此列中更新此值?”
  2. 是否可以通过Hibernate在更新之前进行陈旧的数据检查,以查看应用程序中仍在内存中的值是否已更改?
  3. 以下是相关对象的片段:

    @Entity
    @Table(name = "Object1")
    @XmlRootElement
    public class Object1 implements java.io.Serializable {
       private RefObject1Status statusCd;
    
       @ManyToOne(fetch = FetchType.EAGER)
       @Fetch(FetchMode.JOIN)
       @JoinColumn(name = "statusCd", nullable = false)
       public RefObject1Status getStatusCd() {
          return this.statusCd;
       }
       public void setStatusCd(RefObject1Status cd) {
          this.statusCd = cd;
       }
    
    }
    

    感谢您的时间,

    亚历

1 个答案:

答案 0 :(得分:0)

您可以使用http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/listeners.html中所述的@PreUpdate方法。在该方法中,您可以将值重置为其原始值,但您需要在另一个属性中保留该值的原始值。

您可以使用'@Formula'将原始属性映射为计算属性,然后在加载过程中只读取它:

   @ManyToOne
   @JoinColumn(name = "statusCd")
   public RefObject1Status statusCd;


   @ManyToOne
   @Formula( value = "statusCd")
   public RefObject1Status origStatusCd;

   @PreUpdate
   public void checkStatus(){
      if(!statusCd.isCancel()) statusCd = origStatusCd;
   }

但如果在本地更改了其他属性,并且外部应用程序更新了状态,则无效。 Hibernate永远不会更新单个属性,它总是一次完整记录。

为了使其正常工作,您需要使用版本或时间戳列进行乐观锁定。 您的其他应用程序也需要使用这些列。请参阅http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#d0e5844

如果您使用版本列,并且内部应用程序尝试在外部应用程序已更新版本时更新记录,您将获得OptimisticLockException(或StaleObjectStateException)。