【问题标题】:Bean Validation Through JPA Relationships通过 JPA 关系进行 Bean 验证
【发布时间】:2011-12-08 03:11:54
【问题描述】:

我想使用 Bean Validation 来注释我的实体中的约束,现在的问题是,实体上的关系也会被验证吗?例如假设我有以下实体:

@Entity
@Table(name = "css_empresa")
public class Empresa extends EntidadContactable implements Serializable,
    Convert {
private static final long serialVersionUID = 1L;

@Id
@SequenceGenerator(name = "EMPRESA_ID_GENERATOR", sequenceName = ConstantesSecuencias.SEQ_EMPRESA)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMPRESA_ID_GENERATOR")
@Column(name = "cod_empresa", unique = true, nullable = false)
private Long id;

@Column(name = "num_ruc", precision = 13)
private BigDecimal numRuc;

@Column(name = "num_rup", precision = 15)
private BigDecimal numRup;

@Column(name = "txt_direccion_web", length = 255)
private String txtDireccionWeb;

@NotNull
@Column(name = "txt_nombre", nullable = false, length = 255)
private String txtNombre;

@Column(name = "txt_observaciones", length = 255)
private String txtObservaciones;

@OneToOne
@JoinColumn(name = "cod_usuario")
private Usuario administrador;

// bi-directional many-to-one association to DireccionEmpresa
@OneToMany(mappedBy = "empresa", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<DireccionEmpresa> direccionEmpresas;
    --Rest of code ommited for brevity

DireccionEmpresa 实体声明如下:

@Entity
@Table(name = "css_direccion_empresa")
public class DireccionEmpresa implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@SequenceGenerator(name = "DIREMPRESA_ID_GENERATOR", sequenceName = ConstantesSecuencias.SEQ_DIREMPRESA)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIREMPRESA_ID_GENERATOR")
@Column(name = "cod_direccion_empresa", unique = true, nullable = false)
private Long codDireccionEmpresa;

@Column(name = "sts_predeterminado", nullable = false, length = 1)
private String stsPredeterminado;

@NotNull
@Column(name = "txt_calle_principal", nullable = false, length = 120)
private String txtCallePrincipal;

@NotNull
@Column(name = "txt_calle_secundaria", length = 120)
private String txtCalleSecundaria;

@Column(name = "txt_descripcion", length = 120)
private String txtDescripcion;

@Column(name = "txt_informacion_adicional", length = 120)
private String txtInformacionAdicional;

@NotNull
@Column(name = "txt_numero", nullable = false, length = 10)
private String txtNumero;

@NotNull
@Column(name = "txt_sector", nullable = false, length = 60)
private String txtSector;

现在,问题是在保存 Empresa 时,BeanValidation 是否会检查 DireccionEmpresa 约束?非常感谢。

【问题讨论】:

    标签: jsf-2 jpa-2.0 java-ee-6 bean-validation


    【解决方案1】:

    不,DireccionEmpresa 的约束在持久化 Empresa 的实例时不会被验证。

    通常,级联验证只会在引用(例如普通对象引用或列表)使用@Valid annotation 注释时发生,List&lt;DireccionEmpresa&gt; direccionEmpresas; 则不是这种情况。

    但是,即使该字段使用 @Valid 注释,在 JPA 案例中也不会触发这种级联验证,正如 JPA 2 规范在第 3.6.1.2 节中所说:

    实体关联(单值或多值)不得出现验证级联(@Valid)。 [... 这保证] [...] 在给定的刷新周期内不会对任何实体进行多次验证。

    所以DireccionEmpresa 的约束只会在持久化该类型的实例时自动验证。

    【讨论】:

    • 所以,我应该迭代引用并坚持每一个,以便进行验证?
    • 当您使用CascadeType.ALL 时,引用的对象将在持久化Empresa 实例时自动持久化。这反过来将触发他们的验证,因此您不必自己执行此操作。该规范只是确保在持久化拥有引用的对象和持久化被引用的对象本身时,不会对引用的对象进行两次验证。
    • 好的,所以我对相关实体的引用需要使用“@Valid”注释进行注释。换句话说:'@Valid '@OneToMany(mappedBy = "empresa", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List direccionEmpresas;当 Empresa 对象被持久化时,将触发 DireccionEmpresa 的验证;这样任何约束异常都将被 JPA/JSF(etc) 在嵌套关系中捕获。我猜对了吗?
    • 几乎 :-) JPA 将验证 DireccionEmpresa 的约束,只要这种类型的实例被持久化。由于级联类型ALL,只要您持久化Empresa 实例,就会出现这种情况。在这种情况下,引用处的 @Valid 注释不会产生影响,因为 JPA/Bean Validation 不会(也不能)使用它来执行级联验证,因为在上面概述的持久化 Empresa 实例时.尽管如此,我仍然建议添加 @Valid 注释,以便在手动验证 Empresa 实例时触发级联验证。
    • 我遇到了同样的问题。我添加了@Valid 注释。在我添加之前,它不会验证 baean,现在它会验证 bean 两次.. 为什么?
    猜你喜欢
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多