我有一个名为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
,这看起来过于复杂对于看似简单的要求。任何指针都会受到赞赏。
答案 0 :(得分:1)
可以使用属性javax.persistence.validation.group.pre-persist
,javax.persistence.validation.group.pre-update
和javax.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
}
这种方式永远不会被意外地验证两次