JPA:@OneToMany字段的自定义约束

时间:2013-05-28 11:37:43

标签: java jpa

我有以下情况:

@Entity public class Foo {
  @Id private Long id;

  @OneToMany(mappedBy = "foo")
  @MyCustomConstraint
  private Set<Bar> bars;
}

@Entity public class Bar {
  // ...

  @ManyToOne(optional = false)
  Foo foo;
}

我有自动生成的代码(即无法修改它),用于创建新的Bar并通过调用Foo将其添加到现有的bar.setFoo(foo)setFoo确保将bar添加到foo的集合中。然后自动生成的代码调用persist(bar)。此时我需要运行foo.bars上的自定义约束验证程序(新添加的bar可能会违反它),但事实并非如此。

我的问题:

  1. 这是设计还是我做错了什么?
  2. 我该怎么做才能让它发挥作用?
  3. 修改

    有关自定义约束的更多信息 - 尽管我认为这与问题无关。

    这只是一个javax.validation自定义约束:

    @javax.annotation.Constraint(validatedBy = MyCustomConstraintValidator.class)
    @AllTheOtherAnnotationStuff
    public @interface MyCustomAnnotation {
    }
    
    public class MyCustomConstraintValidator implements ConstraintValidator<MyCustomConstraint, Set /*<Bar>*/ .class> {
      void initialize(MyCustomConstraint a) {}
      boolean isValid(Set /*<Bar>*/ s, ConstraintValidatorContext ctx) { ... }
    }
    

    如果我调用entityManager.persist(foo),则验证约束。如果我拨打entityManager.persist(bar),则不会,即使该栏已新添加到其Foo的集合中。

1 个答案:

答案 0 :(得分:0)

问题在于,当您尝试保留bar时,您不会自动保留其foo。您必须在@ManyToOne注释中明确指定要级联持久操作,或者必须手动持久foo

@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
Foo foo;