Java Hibernate 4.2.2插入@OneToMany集合时不验证实体

Java Hibernate 4.2.2插入@OneToMany集合时不验证实体,java,hibernate,hibernate-validator,Java,Hibernate,Hibernate Validator,我有一个母公司,其子公司与OneToMany有关联: Parent { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent", fetch = FetchType.EAGER) @Size(min = 0, max = 4) List<Child> children = new ArrayList<Child>(); @Transac

我有一个母公司,其子公司与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);
    }
}
Parent{
@OneToMany(cascade=CascadeType.ALL,orphanRemoving=true,mappedBy=“parent”,fetch=FetchType.EAGER)
@尺寸(最小值=0,最大值=4)
List children=new ArrayList();
@交易的
公共无效添加子对象(子对象){
child.setParent(this);
添加(child);
}
}
当我调用
addChild()
方法时,Hibernate不会验证children集合@Size约束,并保持子对象的“原样”,这会导致数据库中的实体无效


为什么Hibernate不验证父实体?

Hibernate会触发子实体的插入,但不会触发父实体的更新。我调试了Hibernate源代码,发现在上述情况下,
org/Hibernate/event/internal/DefaultFlushEntityEventListener.java:isUpdateNecessary()
返回
false
。看起来这是一个必须修复的bug


一种可能的解决方案是进行“假”更改,这会弄脏实体并触发验证过程。

我认为hibernate不应该在调用“add”方法时进行验证,通常验证是在persist时触发的(或者可能是其他一些情况)

/**
*@作者Zilvinas Vilutis
*/
公共类CollectionSizeTest{
私有最终验证器工厂=Validation.buildDefaultValidatorFactory();
私有最终验证器Validator=factory.getValidator();
公共类集合{
@尺寸(最小值=0,最大值=1)
private Collection=new ArrayList();
}
@试验
公共void testCollectionSize(){
CollectionSize underTest=新CollectionSize();
assertTrue(validator.validate(underTest.isEmpty());
未测试。收集。添加(“第一”);
assertTrue(validator.validate(underTest.isEmpty());
测试不足。收集。添加(“第二”);
assertEquals(1,validator.validate(underTest.size());
assertEquals(“大小必须介于0和1之间”,validator.validate(underTest).iterator().next().getMessage());
}
}

该方法被注释为@Transactional-persist(),将被隐式调用。我想知道
@Transactional
如何在域实体类上工作,因为
Spring
将其特性附加到包扫描配置中定义的Springbeans上。我建议将其转移到服务中。在我的情况下,它是一个@Configurable类,我有意使用活动记录模式。不过,谢谢你的建议;)
/**
 * @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() );
    }

}