Java Hibernate 4.2.2插入@OneToMany集合时不验证实体
我有一个母公司,其子公司与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
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() );
}
}