hibernate“动态”java验证框架?
AFAIKJSR-303是标准的bean验证系统
我不知道它是否可以像这样进行验证(我想没有):
- 如果对象设置了“已删除”标志,则无法修改该对象
- 日期传递后,不能更改“开始日期”属性
- 不能减少bean中的某些整数属性
那么,如何处理依赖于对象先前状态的验证呢
我想在hibernate3中解决类似的问题。5-spring3-JPA2环境
谢谢
我的解决方案是搞乱hibernate,重新加载对象以查看旧状态(在逐出新对象之后)。这次我需要一些更聪明的解决方案
# 1 楼答案
另一种完全不同的方法是将验证检查放入属性的setter中。缺点是你会失去陈述性
例如:
# 2 楼答案
听起来,您想要验证的字段(关于以前的状态)都是关于记录的元数据,而不是真实数据。所有这些字段(idDeleted、createdDate等)最好不在域层中,因此不需要验证。我会提出确定&;在数据访问层中设置这些值,以便使用存储库接口的系统不需要知道或关心如何正确设置这些值
如果我关于这些字段是元数据的假设不正确,并且用户输入的数据验证取决于以前的状态,那么我不认为额外查找以前的值是荒谬的,也不应该是不可能的。这对你来说是有道理的。Hibernate本身在then hood下进行查找,以确定在使用其save函数时是插入还是更新
希望你能找到一个合理的解决方案
# 3 楼答案
我不是100%确定它是否可行,但我能想到的唯一方法是创建一个由“新状态”和“旧状态”(瞬态)组成的对象图,并使用自定义约束验证对象图作为一个整体。至少我会这么做
# 4 楼答案
我可能会创建一个瞬态字段,表示前一版本,该版本指向表示其前一状态的数据副本。此对象是在构造时创建的,但由于它被标记为瞬态,因此不会序列化。然后对其进行验证
最简单的实现是添加一个名为makeACopy()的方法,该方法生成对象的副本并将其放入字段中
您可以通过实现Clonable或创建一个可以进行反射的实用程序类来增加复杂性,但这取决于您自己。我建议以后使用makeACopy()和重构,因为这样更容易思考
# 5 楼答案
我不认为使用JSR303验证(或我使用过的任何其他验证框架)可以做到这一点。验证通常是无状态的——您向它传递一个对象的实例,并且您的验证框架会进行测试,以确保对象的当前值是有效的。没有关于对象先前状态的真实知识
您可以做到这一点-只是不需要验证。您可以使用constrained property,也可以使用代理模式或AOP来实现这一点
# 6 楼答案
我也不知道任何现成的解决方案。正如您所怀疑的,JSR-303不会完成这项工作,因为它的验证是“静态的”
但是
一个想法是使用一些AOP技术来实现这一点。所以
这一个我将实现为在每个setter周围注册的代理方法。代理方法将检查“已删除”标志。如果设置为true,将抛出异常,否则将执行原始方法
这个很相似。这一次,您不会访问被截取的setter中的任何其他属性,而是字段和setter参数的原始(尚未更改)值
这与日期相同,唯一的区别是日期类型(日期与整数)
人们可以争论AOP是否是这项任务的一个好选择,但仍然是一个解决方案。我也很怀疑
还有一个问题是,我想你会希望在JPA实体上强制执行这些约束。因此,使用Spring AOP并不是那么容易,因为实体不是Spring管理的