2011-08-31 44 views
0

我有兩個領域類這樣的,第一即Manager似乎Groovy在這兩種情況下行爲不同?

package com.mnm 

class Manager { 
    String name; 
    static hasMany = [ project : Project, tasks : Tasks ] 
    static constraints = { 
    } 
} 

而且即第二個,Project

package com.mnm 

class Project { 
    String projectTitle 
    String projectDescription 
    String description 
    static belongsTo = [ managers: Manager ] 
    static hasMany = [ tasks : Tasks ] 
    static constraints = { 
    } 
} 

我寫集成測試,像這樣(尋找projects名通過使用Manager):

void testCountProject() { 
     def manager = new Manager(name:'Anto').save() 
     manager.addToProject(new Project(projectTitle:'Grails')) 
     manager.addToProject(new Project(projectTitle:'Griffon')) 
     def noOfProjects = Manager.get(manager.id) 
     def found = noOfProjects.project.collect { it.projectTitle } 
     assertEquals(['Grails','Griffon'], found.sort()) 
    } 

那麼沒有錯誤在它和測試通過!但是,當我添加更多的東西到像相同的測試(現在我想反,通過使用Project找到Manager名):

void testCountProject() { 
     def manager = new Manager(name:'Anto').save() 
     def project1 = new Project(projectTitle:'Grails').save() 
     manager.addToProject(project1) 
     manager.addToProject(new Project(projectTitle:'Griffon')) 
     def noOfProjects = Manager.get(manager.id) 
     def found = noOfProjects.project.collect { it.projectTitle } 
     assertEquals(['Grails','Griffon'], found.sort()) 
     def noOfManager = Project.get(project.id) 
     def foundManager = noOfManager.managers.collect { it.name } 
     assertEquals(['Anto'],foundManager) 
    } 

現在我得到的錯誤是這樣的:

No signature of method: com.mnm.Manager.addToProject() is applicable for argument types: (null) values: [null] Possible solutions: addToProject(java.lang.Object), getProject() 

我哪裏出錯了?

在此先感謝。

回答

3

在這兩種情況下,你都有同樣的問題,但第一個不是正確的測試,所以它似乎工作。問題是,默認情況下,所有屬性都不爲空,所以當您僅設置projectTitle時,您的Project實例未通過驗證。

在第一次測試中,您不會重新加載manager實例,因爲get()將Hibernate會話用作第一級緩存,所以仍然使用內存中的一個。如果沖洗,清除會話,迫使它去數據庫會失敗:因爲你呼籲Project實例save()並在驗證失敗時返回null

class MyTest extends GroovyTestCase { 

    def sessionFactory 

    void testCountProject() { 
     def manager = new Manager(name:'Anto') 
     manager.addToProject(new Project(projectTitle:'Grails')) 
     manager.addToProject(new Project(projectTitle:'Griffon')) 
     manager.save(flush: true) 

     sessionFactory.currentSession.clear() 

     def noOfProjects = Manager.get(manager.id) 
     def found = noOfProjects.project.collect { it.projectTitle } 
     assertEquals(['Grails','Griffon'], found.sort()) 
    } 
} 

第二個失敗。您不需要保存Project實例,因爲當包含Manager時,它們將被傳輸保存 - 更多標準模式是您在第一次測試中使用的模式。

您有幾個選項。一個是修復驗證錯誤:)另一個是檢查驗證錯誤。這需要一個單獨的save()調用,這樣你可以訪問非空實例:

def project1 = new Project(projectTitle:'Grails') 
project1.save() 
if (project1.hasErrors()) { 
    // handle errors 
} 
else { 
    manager.addToProject(project1) 
} 

三是failOnError驗證失敗時將拋出一個異常:

def project1 = new Project(projectTitle:'Grails').save(failOnError: true) 
manager.addToProject(project1) 
+0

你能更多地解釋你的意思通過「,默認情況下所有的屬性都不是null,所以當你只設置了」projectTitle「時,你的Project實例就無法通過驗證。 ? –

+0

驗證?但是在我的領域類中,我根本沒有做過任何類型的驗證:/那麼驗證失敗如何? –

+1

默認情況下,所有屬性都是必需的。你可以用一個約束'nullable:true'來改變它。所以如果你創建一個新的'Project'並且只設置'projectTitle',你會得到'projectDescription'和'description'的驗證錯誤。調用'save()'首先調用'validate()'以確保不會將無效數據推送到數據庫。你可以明確地調用'validate()',但它也是爲你完成的。 –

相關問題