2011-05-18 38 views
0

我有兩個領域類雙向一對一關聯:Grails中刪除雙向one-to-one關聯

class Nose { 

    String str1 

    static belongsTo = [face:Face] 

} 

class Face { 

    String str1 

    static hasOne = [nose: Nose] 

} 

控制器

class NoseController { 
    def create() { 
    nose.properties = params 
    nose.save(flush: true) 
    } 

    def delete() { 
    def nose = Nose.get(params.id as long) 
    nose.delete(flush: true) 
    } 
} 

class FaceController { 

    def create() { 
     def face = new Face()   
     def nose = Nose.get(params.id as long) 

     if(!nose){ 
     face.nose = nose 
     face.properties = params 
     face.save(flush: true) 

     nose.face = face 
     nose.properties = params 
     nose.save(flush:true) 
     }else{ 
     face.properties = params 
     face.save(flush: true) 
     } 
    } 

    def delete() { 
     def face = Face.get(params.id as long) 
     face.delete(flush: true) 
    } 
} 

創建鼻子面對對象後,我不能刪除更新他們。 當我要刪除我臉弄例外:

org.springframework.dao.DataIntegrityViolationException:外鍵約束 違反試圖在 org.grails.hbase.gorm.DeletePersistentMethod ID爲1,刪除teastrelation.Face .invoke(DeletePersistentMethod.groovy:66) 在org.grails.hbase.gorm.PersistentMethod $ invoke.call(來源不明) 在org.grails.hbase.gorm.PersistentMethod $ invoke.call(來源不明)

對於在FaceController中刪除我已更改刪除操作:

def delete() { 
    def face = Face.get(params.id as long) 
    def nose = Nose.get(face.nose.id) 

    face.nose = null 
    nose.face = null 
    nose.save(flush:true) 
    face.save(flush:true) 
    face.delete(flush: true) 

    render params.id 

} 

,只有經過它,我可以刪除面對對象,但它拋出以下異常:

錯誤gorm.SavePersistentMethod - 無法得到空 對象java.lang中的財產「類」 .NullPointerException:對在 org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56) 在 org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper 空對象無法獲取財產 '類'。 java:156) 在 org.codehaus.groovy.runtime.callsite.PojoMetaClassGetPropertySite.callGetProperty(PojoMetaClassGetPropertySite.java:41)

當我想更新Face對象,我得到了以下異常:

ERROR association.ReferenceTable - 未找到參考表條目, row = [79,78,69,84,79,79,78,69,95,79,78,79,84,79,79,78, 69,95 ,68,79,77,65,73,78,50,95,0,0,0,0,0,0,1]

ERRO R gorm.SavePersistentMethod - 無法在null上獲取屬性「類」 對象java.lang.NullPointerException:無法在org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56)上獲取 空對象 上的屬性'class ) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper。的java:156) 在org.codehaus.groovy.runtime.callsite.PojoMetaClassGetPropertySite.callGetProperty(PojoMetaClassGetPropertySite.java:41)

我使用的grails 1.3.2和HBase的-0.2.4插件,我無法使用映射..

我在做什麼錯?

我已經花了很多時間在這個問題..請幫助,如果任何人都可以。

回答

1

我創建了一個簡單的應用程序來模擬您的問題。在我的例子中,我遵循最佳實踐,即編寫服務來管理對象和一些測試。注意,Domain1Controller上的創建方法調用save(flush:true) 3次(d1兩次,d2一次),這可能不太好,可能是你的問題。

這裏是我做過什麼

域1級:

package com.example 

class Owner { 
    String example; 
    static constraints = { 
     friend unique:true 
    } 
    static hasOne = [friend: Owned] 
} 

域類2

package com.example 

class Owned { 

    String name; 
    static constraints = { 
    } 
    static belongsTo = [owner: Owner] 
} 

服務來管理這些領域類

package com.example 

class OwnerService { 

    static transactional = true 

    def saveNewOwnerAndOwned(ownerField, ownedField){ 
     def owner = new Owner(example: ownedField) 
     def owned = new Owned(name: ownedField) 

     owner.friend = owned 
     // since the relationship is bidirectional, need to set up 
     // the references both ways 
     owned.owner = owner 

     owner.save(flush: true) 
     return owner 
    } 

    def deleteOwner(id) { 

     def toDelete = Owner.get(id) 
     toDelete.delete(flush:true) 

    } 

    def deleteOwnedOfOwner(ownerId) { 
     def owner = Owner.get(ownerId) 
     def owned = owner.friend 

     // must break the relationship 
     owner.friend = null 

     owned.delete(flush: true); 
    }  
} 

測試,以確定它的瓦特奧金德

package com.example 

class OwnerServiceIntegrationTests extends GroovyTestCase { 

    def ownerService 
    def sessionFactory 

    public void testSave(){ 
     def owner = ownerService.saveNewOwnerAndOwned("im an owner", "im owned"); 

     assertNotNull(owner) 
     assertNotNull(owner.id) 
     assertNotNull(owner.friend) 
     assertNotNull(owner.friend.id) 
    } 

    public void testDelete() { 

     def owner = ownerService.saveNewOwnerAndOwned("im an owner", "im owned"); 
     def id = owner.id 
     def ownedId = owner.friend.id 
     ownerService.deleteOwner(id); 

     // since the integration tests hit an actual db 
     // clear the session so when i start testing im sure its accurate 
     def session = sessionFactory.getCurrentSession() 
     session.clear() 

     // make sure everything was deleted, i.e. not in db 
     assertNull(Owner.get(id)) 
     assertNull(Owned.get(ownedId)) 
    } 

    public void testDeleteOwned() { 
     def owner = ownerService.saveNewOwnerAndOwned("im an owner", "im owned"); 
     def id = owner.id 

     ownerService.deleteOwnedOfOwner(id); 

     def session = sessionFactory.getCurrentSession() 
     session.clear() 

     owner = Owner.get(id) 
     // make sure owner still there but friend is not 
     assertNotNull(owner) 
     assertNull(owner.friend) 
    } 


} 
+0

在這種情況下,我們沒有得到bidirectin協議,有我們嗎?因爲擁有=空(它沒有被保存)。對於create方法中的雙向關聯,我寫了下面的代碼:def owned = new Owned(name:ownedField)owned.save(flush:true) def owner = new Owner(例如:ownedField) owner.friend = owned owner。保存(flush:true) owned.owner =擁有者owned.save(flush:true)之後我嘗試刪除它們的方法,但我得到了異常。如果你再試一次,請張貼你的結果.. – Bella 2011-05-19 08:07:52

+0

是的,你做。你有belongsTo和hasOne(字段指向對方)---這是雙向的。如果你不想雙向,那麼把孩子'擁有的'類的引用取出給它的父代,它將是單向的。 – hvgotcodes 2011-05-19 12:34:38

+0

不,我希望他們是雙向的...我的意思是,在這個例子中,如果寫:owner.friend = owned owned.owner = owner owner.save(flush:true) 並保存所有者並且不保存所有權,它不會是雙向的。爲了使它成爲雙向的,我必須調用svae(flush:true)方法3次。 – Bella 2011-05-19 12:44:33