禁用合并/更新的Hibernate验证

时间:2014-09-15 15:44:39

标签: java hibernate hibernate-validator

我有一个名为Order的POJO如下:

public class Order {

    @Id
    @GeneratedValue
    @Column(name="id")
    protected int id;

    @NotNull
    @Future
    protected Date desiredProcessingDate;

    protected Date actualProcessingDate;
}

如您所见,必须指定desiredProcessingDate,并且必须在将来使用。用户将通过表单提交新订单并指定desiredProcessingDate,其正在按预期进行验证。然后,订单将通过sessionFactory.getCurrentSession().persist(order);

保留到数据库中

以后,计划的服务将从数据库中检索订单,处理它并使用当前时间戳标记actualProcessingDate

但是,当此服务调用sessionFactory.getCurrentSession().merge(order);时,验证会再次启动并失败,因为desiredProcessingDate现在已经过去了。

似乎我需要做的是告诉merge(order)操作不要验证,但我不确定如何执行此操作。

如果这是不可能的,那么似乎只能绕过它就是编写一个类级别的自定义验证器,它只检查desiredProcessingDate将来actualProcessingDate == null,这看起来过于复杂对于看似简单的要求。任何指针都会受到赞赏。

2 个答案:

答案 0 :(得分:1)

可以使用属性javax.persistence.validation.group.pre-persistjavax.persistence.validation.group.pre-updatejavax.persistence.validation.group.pre-remove配置JPA中的验证行为。这些属性的值是以逗号分隔的列表,列出了每个给定JPA生命周期事件的目标验证组的完全限定类名,例如:

<property name="javax.persistence.validation.group.pre-persist" value="javax.validation.groups.Default,com.acme.PrePersist"/>    
<property name="javax.persistence.validation.group.pre-update" value="javax.validation.groups.Default"/>

解决您的问题的方法是将@Future约束添加到“PrePersist”组中,在这种情况下,它只会在持久性而非更新时进行验证。

答案 1 :(得分:-1)

实际上我真的会在Backing Bean中执行此代码,然后在实体本身,我实际上会强调这一点,但这取决于你。此代码将以持久保存Order的方法编写,当然@Future将被完全删除。

所以在支持bean中你会有

//psuedocode
void submitButtonHasBeenPressed(entity){

Date dNow = new Date();
//SimpleDateFormat ft = new SimpleDateFormat("yyyy"); if you need this
if(desiredProcessDateTheUserEnteredInTheField > dNow){
entity.setDesiredProcessingDate(desiredProcessDateTheUserEnteredInTheField);
 }
   else{

   System.out.println("ERROR OCCURED IN VALIDATION");
   FacesContext.getCurrentInstance().addMessage(null,"ERROR OCCURED IN VALIDATION");
   //or show an error Spring style

   }

这种方式永远不会被意外地验证两次