开发者

Grails Delete bi-directional one-to-one association

I have two domain classes with bidirectional one to one association:

Domains

class Nose {

  String str1

  static belongsTo = [face:Face]

}

class Face {

  String str1

  static hasOne = [nose: Nose]

}

Controllers

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开发者_StackOverflow = Face.get(params.id as long)
      face.delete(flush: true)
   }
}

After creating Nose and Face objects, I can't delete and update them. When I want to delete Face I get exception:

org.springframework.dao.DataIntegrityViolationException: Foreign key constraint violation trying to delete teastrelation.Face with id 1 at org.grails.hbase.gorm.DeletePersistentMethod.invoke(DeletePersistentMethod.groovy:66) at org.grails.hbase.gorm.PersistentMethod$invoke.call(Unknown Source) at org.grails.hbase.gorm.PersistentMethod$invoke.call(Unknown Source)

For removing in FaceController I have changed remove action:

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

}

and only after it I can delete Face object, but it throw the following exception:

ERROR gorm.SavePersistentMethod - Cannot get property 'class' on null object java.lang.NullPointerException: Cannot get property 'class' on null object at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:156) at org.codehaus.groovy.runtime.callsite.PojoMetaClassGetPropertySite.callGetProperty(PojoMetaClassGetPropertySite.java:41)

When i want to update Face object, i got the following exception:

ERROR associations.ReferenceTable - Reference table entry not found, row=[79, 78, 69, 84, 79, 79, 78, 69, 95, 79, 78, 69, 84, 79, 79, 78, 69, 95, 68, 79, 77, 65, 73, 78, 50, 95, 0, 0, 0, 0, 0, 0, 0, 1]

ERROR gorm.SavePersistentMethod -Cannot get property 'class' on null object java.lang.NullPointerException: Cannot get property 'class' on null object at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:156) at org.codehaus.groovy.runtime.callsite.PojoMetaClassGetPropertySite.callGetProperty(PojoMetaClassGetPropertySite.java:41)

I use grails 1.3.2 and hbase-0.2.4 plugin and I can not use mapping..

What am I doing wrong ?

I have already spent a lot of time on this problem.. please help if anyone can.


I created a simple application to model your issue. In my example, I followed best practices, namely writing a service to manage the objects and some tests. As a note, the create method on your Domain1Controller calls save(flush:true) 3 times (twice on d1 and once on d2), which is probably not good and might be your issue.

Here is what I did

domain class 1:

package com.example

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

domain class 2

package com.example

class Owned {

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

service to manage those domain classes

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);
    }     
}

tests to make sure its working

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜