openxava / 文档 / 第二十章:删除时验证

课程:1. 入门教学 | 2. 基本域模型(上) | 3. 基本域模型(下) | 4. 优化用户界面 | 5. 敏捷开发 | 6. 映射式超类继承 | 7. 实体继承 | 8. 视图继承(View) | 9. Java 属性 | 10. 计算属性 | 11. 用在集合的 @DefaultValueCalculator | 12. @Calculation 和集合总计 | 13. 从外部文件的 @DefaultValueCalculator | 14. 手动更改 schema | 15. 多用户时默认值的计算 | 16. 同步持久属性和计算属性 | 17. 从数据库中的逻辑 | 18. 使用 @EntityValidator 进行验证 | 19. 验证替代方案 | 20. 删除时验证 | 21. 自定义 Bean Validation 注解 | 22. 在验证中调用 REST 服务 | 23. 注解中的属性 | 24. 改进标准行为 | 25. 行为与业务逻辑 | 26. 参照与集合 | A. Architecture & philosophy | B. Java Persistence API | C. Annotations | D. Automated testing

目录

第二十章:删除时验证
删除时使用 @RemoveValidator 验证
删除时使用 JPA 回调方法验证
哪一个是最佳的验证方法?
总结
在上一章,我们学到在保存时验证的替代方案。在本章,我们将研究在删除时的验证。

删除时使用 @RemoveValidator 验证

到目前为止我们所看到的验证都是在实体被修改时执行的,但有时在需要删除实体之前执行验证,并使用它来取消实体删除。
我们将修改应用程序,当订单有关联的发票时会拒绝删除订单。要实现这一点,得用 @RemoveValidator 注解 Order 实体,如下:
@RemoveValidator(com.yourcompany.invoicing.validators.OrderRemoveValidator.class) // 带有验证的类
public class Order extends CommercialDocument {
现现在,在删除订单之前,会执行 OrderRemoveValidator 中的逻辑,如果验证失败,则不会删除订单。我们看看验证器的代码:
package com.yourcompany.invoicing.validators; // 在验证器包

import com.yourcompany.invoicing.model.*;
import org.openxava.util.*;
import org.openxava.validators.*;
 
public class OrderRemoveValidator
    implements IRemoveValidator { // 必须实现 IRemoveValidator
 
    private Order order;
 
    public void setEntity(Object entity) // 在验证之前将使用此方法注入要移除的实体
        throws Exception 
    {
        this.order = (Order) entity;
    }
 
    public void validate(Messages errors) // 验证逻辑
        throws Exception
    {
        if (order.getInvoice() != null) {
            // 通过在errors添加消息,验证将失败並而中止刪除
            errors.add("cannot_delete_order_with_invoice");
        }
    }
}
验证的逻辑在 validate() 方法中。在调用它之前,要验证的实体会使用 setEntity() 注入。如果在 errors 中添加消息,则验证将失败并且实体不会被删除。您必须在 invoicing/src/main/resources/i18n/invoicing-messages_zh.properties 文件中添加:
cannot_delete_order_with_invoice=无法删除带有发票的订单
如果您现在尝试删除带有关联发票的订单,您将收到一条错误消息,并且不会删除。
如您所见,使用 @RemoveValidator 并不难,但很冗长。您必须编写一个全新的类来添加一个简单的 if。现在让我们研究一个更简短的替代方案

删除时使用 JPA 回调方法验证

我们将尝试用另一种更简单的方法来执行删除时的验证,只需将验证逻辑从验证器类移动到 Order 实体,在本例中为 @PreRemove 方法。
首先,从您的项目中删除 OrderRemoveValidator 类。还要从您的 Order 实体中删除 @RemoveValidator 注解:
//@RemoveValidator(com.yourcompany.invoicing.validators.OrderRemoveValidator.class) // 删除 @RemoveValidator
public class Order extends CommercialDocument {
我们刚刚把验证删除了。现在我们再次添加此功能,但现在是在 Order 类中添加 validateOnRemove() 方法:
@PreRemove // 在删除实体前
private void validateOnRemove() {
    if (invoice != null) { // 验证逻辑
        throw new javax.validation.ValidationException( // 抛出运行时异常
            XavaResources.getString( // 並获取消息
                "cannot_delete_order_with_invoice"));
    }
}
此验证将在删除订单之前执行。如果失败,则会抛出 ValidationException。您可以抛出任何运行时异常以中止删除。只需在实体中添加一个方法就能实行验证了。

哪一个是最佳的验证方法?

您已经学到了几种在模型类中进行验证的方法。至于哪一个是最好的?它们都是最佳的选项。因为这取决于您面对的情况和个人喜好。如果您有一个重要且可在整个应用程序中重复使用的验证,那么使用 @EntityValidator 和 @RemoveValidator 是一个不错的选择。另一方面,如果你想在 OpenXava 之外使用你的模型类而不使用 JPA,那么在 setter 中使用验证会更好。
在我们的示例中,我们使用 @AssertTrue 进行"订单须已送达才能添加至发票中"的验证,并使用 @PreRemove 进行删除时的验证,因为这是最简单的方案。

总结

在本章,您学到了几种在 OpenXava 应用程序中进行验证的方法。在下一章,您将学习如何创建自定义的 Bean Validation。这会非常有用!

下载本课源代码

对这节课有什么问题吗? 前往论譠 一切都顺利吗? 前往第二十一章