2011-08-09 50 views
6

我想知道这个简单问题的答案。创建实体规则

当我创建一个实体对象,我想限制一个属性的设置(例如我不想让任何人设置一个整数值小于1的属性),我应该在这个属性的setter还是应该在处理这些对象的类中检查后者的限制?一般来说,我可以实现getter和setter,但是只要我的getter返回并设置set属性,我就可以实现吗?

我知道在java中有一些规则(代码约定),所以我不想破坏它们中的任何一个。

在此先感谢,希望我的问题对我可能犯的任何语法错误都足够清楚和抱歉:/。

回答

6

是的getters/setters对此很有用。

例如:

public void setAge(int age){ 
if(age < 0){ 
    throw new IllegalArgumentException("Invalid age : " + age); 
    //or if you don't want to throw an exception you can handle it otherways too 
} 
} 

您也可以使用Java-EE的Bean Validators

public class Person{ 

    @Min(value = 0) 
    @Max(value = 99) 
    private Integer age; 

    //some other code 
} 
+0

谢谢!您的帮助非常感谢,并且很高兴知道其他方法:) – VaclavDedik

+0

欢迎您:) –

1

这是获得者和制定者的目标。

如果我们不能在这些方法中添加一些行为,那么......为什么我们不使用公共属性?

2

我的首选方法是使用JSR 303(Bean验证API),以确保该类的属性是有效的。

在setter中执行验证是完全可以的,但这并不总是一种理想的方法。有可能会混淆不相关的多个上下文的需求。例如,您的某些属性决不能从用户界面设置,而应该在被保留之前由服务计算。在这种情况下,将这个逻辑放在setter中是不可取的,因为你需要知道setter被调用的上下文;您需要在UI层和持久层中应用不同的规则。 JSR 303允许您使用验证组来区分这些问题,以便您的UI验证组与您的持久性验证组不同。

在JPA 2.0中,当您使用的是由JSR 303的验证评估约束注释类,持久化提供商可以自动评估对PrePersistPreUpdatePreRemove这些限制(通常没有这样做;见下文)的生命周期事件实体。要在您的JPA提供程序中执行实体验证,您必须在persistence.xml文件中指定validation-mode元素或javax.persistence.validation.mode属性;值必须是AUTO(默认值)或CALLBACK(而不是NONE)。

Bean验证提供程序的存在足以确保在JPA实体生命周期事件上进行验证,因为默认值为AUTO。在Java EE 6应用程序服务器中,您可以默认获得此信息; Glassfish使用Hibernate Validator的JSR 303的RI实现,而且EclipseLink也可以很好地工作。

CALLBACK模式将允许您覆盖触发生命周期事件时要应用的验证组。默认情况下,默认的Bean验证组(Default)将针对更新和持久事件进行验证;删除事件不涉及任何验证。 CALLBACK模式允许您使用属性javax.persistence.validation.group.pre-persist,javax.persistence.validation.group.pre-updatejavax.persistence.validation.group.pre-remove为这些事件指定不同的验证组。

请记住,虽然我上面发布的Bean Validation API文档链接来自Java EE 6 API文档,但可以在Java EE容器之外使用JSR 303验证。

+0

顺便说一下,JSR 303的参考实现是Hibernate Validator框架。请参阅:http://www.hibernate.org/subprojects/validator.html – MicSim

0

吸气剂和吸附剂非常适合添加限制,就像Jigar Joshi在他的回答中所做的一样。这样,您可以立即获得反馈,并在引入问题时处理问题。

另一个解决方案是使用对象验证(类似于JSR-303实现),它允许您使用最小值和最大值对字段进行注释。像

@Min(value=1) 
private int myvalue; 

东西然后你就可以一气呵成验证整个对象并获取所有信息,如果您有其他的限制领域。这在任何地方显然都没有用,但如果它符合你的需要,它是一种选择。

最后,当你说“实体”时,我想到了存储在数据库中或与ORM工具相关的东西。如果是这样的话,你会想要小心你在吸气剂中的作用。例如,如果您在getter中执行延迟初始化,则某些ORM供应商会将实体标记为脏,并尝试将其刷新到数据库,可能会导致意外写入。