如何仅在mvc层上排除验证属性(并保留数据库层)?

时间:2018-04-18 13:33:26

标签: java spring hibernate spring-mvc spring-web

我想对数据库持久性和webservice json请求使用相同的bean。

问题:我有一个属性,永远不应该由webservice用户设置,但在持久性之前由应用程序填充。数据库中的字段标记为非空,因此域验证为:@NotNull

但是如果我添加这个,那么spring-mvc也将验证传入的json请求并在未设置id时抛出异常(但是需要)。

问题:如何仅在mvc层上排除某些验证属性?

@Entity
public class Person {
    @Id
    @NotNull
    @JsonIgnore //has no effect
    private String id; //to be set by application before persistance

    private String name;
    private int age;
}

@RestController 
public class PersonController {
    @PostMapping
    public void post(Person p) {

    }
}

1 个答案:

答案 0 :(得分:2)

您所描述的要求是能够根据相应的上下文为同一个bean定义不同的约束。在MVC层中,您希望id可以为空,并且您希望它的持久层不为null。

您可以使用Validation Groups来实现此要求。

您首先介绍了持久性验证案例的新界面,请说:

public interface PersistenceGroup {

}

然后将bean更改为:

@Entity
public class Person {
    @Id
    @NotNull(groups = PersistenceGroup.class)
    private String id; //to be set by application before persistance

    private String name;
    private int age;
}

@RestController 
public class PersonController {
    @PostMapping
    public void post(Person p) {

    }
}

这导致 @NotNull 仅针对给定组进行验证。因为默认情况下javax.validation.groups.Default组用于验证,因此您的MVC不会检查@NotNull 。现在我们告诉Hibernate在其 BeanValidationEventListener 被激活时使用你的组,以便持久化,更新或删除你的实体。这可以通过设置以下属性的相应属性来完成(请参阅docs):

  • javax.persistence.validation.group.pre-persist
  • javax.persistence.validation.group.pre-update
  • javax.persistence.validation.group.pre-除去

您的用例示例:

<hibernate-configuration>
<session-factory>
    ...
    <property name="javax.persistence.validation.group.pre-persist">
        javax.validation.groups.Default,your.package.PersistenceGroup
    </property>
    <property name="javax.persistence.validation.group.pre-update">
        javax.validation.groups.Default,your.package.PersistenceGroup
    </property>
    ...