2013-12-14 58 views
0

我有一對多的關聯父實體向子實體:的Hibernate 4.2.2未插入時驗證實體到其@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

Hibernate爲子實體觸發INSERT,但不觸發父實體的UPDATE。我已經調試過Hibernate源代碼,發現在上述情況下org/hibernate/event/internal/DefaultFlushEntityEventListener.java:isUpdateNecessary()返回false。看起來這是一個必須修復的錯誤。

一個可能的解決方案是做一個'虛假'的變化,這會弄髒實體並觸發驗證過程。

0

我不認爲hibernate應該在調用「add」方法的時候驗證,通常驗證是在persist(或可能是其他一些情況)時觸發的。

/** 
* @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()); 
    } 

} 
+0

的方法被註釋爲@Transactional - 留存()將被隱式調用 – Ivan

+0

我不知道這個'@ Transactional'爲你工作在一個域實體類爲'Spring'重視在Spring bean的定義方面對包掃描配置。我會建議將其移出服務。 – Zilvinas

+0

這是一個@Configurable類,在我的情況下,我有意使用活動記錄模式。感謝您的建議,儘管;) – Ivan

相關問題