如何确保真正的一对多关系

时间:2012-10-15 01:31:20

标签: grails gorm

我在实体之间有一对多的关系 - RentalUnit和Review。所有测试都运行正常,除非我将相同的评论添加到不同的RentalUnit实例,如下所示:

def review3 = Review.build().save(flush: true)
def rentalUnit2 = RentalUnit.build().
    addToReviews(review2).addToReviews(review3).save(flush: true)
assert rentalUnit.reviews.contains(review2)

似乎GORM和addTo*方法似乎并不关心我是否添加相同的Review实例,因此我猜我的域类中缺少某些内容。那会是什么?

感谢您的帮助

P.S。

class Review {
    String submittedBy
    String content
    String dateReceived
    boolean isApproved

    static belongsTo = RentalUnit

    static mapping = {
        content type: 'text'
    }

    static constraints = {
        submittedBy blank: false, size: 3..50
        content blank: false, size: 5..2500

    }
}

class RentalUnit {
    String name
    String nickname
    Address address
    static hasMany = [reviews:Review]

    static mapping = {
        reviews cascade: "all-delete-orphan"
    }

    static constraints = {
        name blank: false, unique: true, size: 4..10
        nickname blank: false, size: 5..60
    }
}

1 个答案:

答案 0 :(得分:1)

是的,它并不关心 - 它不会改变任何其他对象的属性。即使是关系的另一端 - review2.rentalUnit(如果存在这样的字段)也会在这里为空。

下次从数据库加载对象时,审核将从rentalUnit.reviews(或review2.rentalUnit将被分配)中消失。

您可以手动分配review2.rentalUnit并验证它是否已添加到另一个RentalUnit,但该分配不会造成任何伤害。

编辑:让我们一步一步地完成代码。

rentalUnit1.addToReviews(review2)

此处review2已添加到rentalUnit1.reviews。未分配review2.rentalUnit,但在数据库中保存后,它将指向rentalUnit1RentalUnit.reviews字段的唯一持久表示是子到父参考字段Review.rentalUnit

def rentalUnit2 = ...
rentalUnit2.addToReviews(review2).addToReviews(review3).save(flush: true)

此处review2已添加到rentalUnit2.reviewsreview2.rentalUnit未再次分配。 review2 rentalUnit1.reviews未从rentalUnit2移除,但保存后,在数据库中,它将指向assert rentalUnit1.reviews.contains(review2)

review2

rentalUnit1.reviews未从rentalUnit1中移除,因此断言将通过。但是,在下一个会话中,rentalUnit2review将拥有正确的rentalUnit2 s集 - 只有review2才会有class RentalUnit { RentalUnit addToReviewsAndCheck(Review r) { if (r.rentalUnit == this) return; if (r.rentalUnit != null) { r.rentalUnit.removeFromReviews(r) } r.rentalUnit = this addToReviews(r) } }

现在,如果您希望始终保持Java表示形式的一致性,请使用以下方法:

{{1}}

但对我来说这是一种矫枉过正。