0

エンティティ間に 1 対多の関係があります - 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 インスタンスを追加しても気にしないように見えるので、ドメイン クラスに何かが欠けていると推測しています。それは何でしょう?

助けてくれてありがとう

ps

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
    }
}
4

1 に答える 1

1

はい、気にしません。他のオブジェクトのプロパティは変更しません。関係の反対側についても - review2.rentalUnit(そのようなフィールドが存在する場合) ここでは null になります。

次にオブジェクトがデータベースからロードされると、レビューは消えますrentalUnit.reviews(または割り当てられます)。review2.rentalUnit

review2.rentalUnit手動で割り当てて、別の に追加されているかどうかを検証できますが、割り当てによってRentalUnit害はありません。

edit : コードを順を追って見ていきましょう。

rentalUnit1.addToReviews(review2)

ここreview2に を追加しrentalUnit1.reviewsます。review2.rentalUnitは割り当てられていませんが、データベースに保存した後は を指しますrentalUnit1。fieldの唯一の永続的な表現RentalUnit.reviewsは、子から親への参照フィールドですReview.rentalUnit

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

ここreview2に を追加しrentalUnit2.reviewsます。review2.rentalUnit再び割り当てられることはありません。review2は削除されませんがrentalUnit1.reviews、保存後、データベースでは を指しrentalUnit2ます。

assert rentalUnit1.reviews.contains(review2)

review2は から削除されていないrentalUnit1.reviewsため、アサーションはパスします。しかし、次のセッションrentalUnit1rentalUnit2は、正しいセットのreviewsrentalUnit2を持つことになりますreview2

ここで、Java 表現の一貫性を常に維持したい場合は、次のようなメソッドを実装します。

class RentalUnit {
    RentalUnit addToReviewsAndCheck(Review r) {
         if (r.rentalUnit == this) return;
         if (r.rentalUnit != null) {
             r.rentalUnit.removeFromReviews(r)
         }
         r.rentalUnit = this
         addToReviews(r)
    }
}

しかし、それは私にとってはやり過ぎです。

于 2012-10-15T08:48:40.930 に答える