2016-10-11 23 views
0

我很确定我做错了什么,因为这显然有效。简化类:grails 2.5.1 remove从一对多给出奇怪的行为(不是删除)

class Person { 
    String name 
    static hasMany = [cats:Cat] 
} 

class Cat { 
    String name 
    Person person 
    static belongsTo = Person 
    static constraints = { 
    person(nullable:false) 
    } 
    String toString() { 
    "${person.name}-${name}" 
    } 
} 

简单的东西,一个人有很多猫,猫只能属于一个人。

现在,当我做了一个服务类之后,我得到了奇怪的结果:

delete(Cat cat) { 
    Person owner = cat.person 
    log.debug("Cats before removing ${cat} (id=${cat.id}): ${owner.cats} -- ${owner.cats*.id}") 
    owner.removeFromCats(cat); 
    log.debug("Removed from owner ${owner}, owner now has ${owner.cats} -- ${owner.cats*.id}") 
    log.debug("Cat to delete is now: ${cat} and belongs to... ${cat.person}") 
    cat.delete(flush:true) 
} 

和错误是“对象将被重新保存,等等等等”

org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations) 

怪异位是调试结果,当调用删除“Bob”拥有的猫“Fluffy”时:

Cats before removing Bob-Fluffy (id=1356): [Bob-Fluffy] -- [1356] 
Removed from owner Bob, owner now has [null-Fluffy] -- [1356] 
Cat to delete is now: null-Fluffy and belongs to... null 

什么事情在“removeFrom”实际上不是从集合中删除对象?我清理并重新编译。对于为什么我不能删除这个对象,我几乎不知所措。

回答

0

它看起来像什么在我的情况下发生的是cat.person已经越来越陈旧不知何故,即使它是该方法的第一件事。调用cat.refresh()不起作用,但在从猫中提取后调用owner.refresh()

0

我会尝试删除该领域的人作为人的人,只留下属于关联领域这样

class Cat { 
    String name 
    static belongsTo = [person:Person] 
    static constraints = { 
    person(nullable:false) 
    } 
    String toString() { 
    "${person.name}-${name}" 
    } 
} 
+0

虽然这是更清晰的代码,但做出这一改变并不能解决我的问题。 – Trebla

+0

你还可以在删除猫时尝试删除flush:true选项吗? –

+0

那里没有运气,要么......它成功地通过了删除步骤,但在下次事务导致刷新时抛出相同的错误 – Trebla

0

我会改变领域类。

class Person { 
    String name 
    static hasMany = [cats:Cat] 
} 

class Cat { 
    String name 
    Person person 
    // no need to add belongs to property here. it creates a join table that you may not need 
    static constraints = { 
    person(nullable:false) 
} 

String toString() { 
    "${person.name}-${name}" 
    } 
} 

在服务类

delete(Cat cat) { 
    cat.delete(flush:true) 
} 

一旦你做出域中的变化,开始一个新的数据库,因为该模式将发生变化。

我认为应该解决你的问题。

+0

我绝对需要连接表...猫/人范例很愚蠢,但它简化了例如模型。猫不能存在,除非它是人的一部分(或者说,当不是人的一部分时是没有意义的)。由于这是具有多年数据的生产代码,因此也不可能从新的数据库开始。 – Trebla