我有一个与其子女有OneToMany关联的父实体:
Parent {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent", fetch = FetchType.EAGER)
@Size(min = 0, max = 4)
List<Child> children = new ArrayList<Child>();
@Transactional
public void addChild(Child child) {
child.setParent(this);
children.add(child);
}
}
当我调用addChild()
方法时,Hibernate不会验证子集合@Size约束并将子节点“保持原样”,从而导致数据库中的实体无效。
为什么Hibernate不验证父实体?
答案 0 :(得分:1)
Hibernate触发子实体的INSERT,但不会触发父实体的UPDATE。我调试了Hibernate源代码,发现org/hibernate/event/internal/DefaultFlushEntityEventListener.java:isUpdateNecessary()
在上述情况下返回false
。看起来这是一个必须修复的错误。
一种可能的解决方案是制造一个假的&#39;改变会弄脏实体并触发验证过程。
答案 1 :(得分:0)
我不认为hibernate应该在调用“add”方法时进行验证,通常验证是在持久化时触发的(或者可能是其他一些情况)。
/**
* @author Zilvinas Vilutis
*/
public class CollectionSizeTest {
private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
private final Validator validator = factory.getValidator();
public class CollectionSize {
@Size( min = 0, max = 1 )
private Collection<String> collection = new ArrayList<String>();
}
@Test
public void testCollectionSize() {
CollectionSize underTest = new CollectionSize();
assertTrue( validator.validate( underTest ).isEmpty() );
underTest.collection.add( "first" );
assertTrue( validator.validate( underTest ).isEmpty() );
underTest.collection.add( "second" );
assertEquals( 1, validator.validate( underTest ).size() );
assertEquals( "size must be between 0 and 1", validator.validate( underTest ).iterator().next().getMessage() );
}
}