5

私はgrails2.0.0を使用しています。Member、Product、ProductTypeの3つのオブジェクトがあります。メンバーは多くの製品を持っており、1対多の関係にあります。ProductはProductType(参照テーブル)を指し、多対1の関係です。私の質問は、製品の削除についてです。あるシナリオでは機能し、別のシナリオでは機能しません。読む。

以下のマッピングの大まかな概要:

Member.groovy:

class Member  {
   Long id
   ....
   SortedSet products
   static hasMany = [products:Product]
   static mapping = {
        table 'T_MEMBER'
        id column:'MEMBER_ID'...
       products cascade: "all-delete-orphan"
   }
}

Product.groovy:

class Product {
   Long id
   ProductType productType
   ...
   static belongsTo = [member:Member]
   static mapping = {
        table 'T_PRODUCT'
        id column:'PRODUCT_ID'
        member column: 'MEMBER_ID'
        productType column: 'PRODUCT_TYPE'
        ...
   }
}

ProductType.groovy:

class ProductType {
   Long id
   ..
   static mapping = {
        table 'T_PRODUCT_TYPE'
        id column:'PRODUCT_TYPE', generator:'assigned'
    ...
   }
}

クライアントサービスコードを取得しました。その概要は...

    if((newMember.products) && (newMember.products.size() >0)) {
        def addList = newMember.products - existingMember.products
        def removeList = existingMember.products- newMember.products
        removeList.each { product ->
            existingMember.removeFromProducts(product)
        }
        addList.each {product ->
            existingMember.addToProducts(product)
        }
    }

ここまでは順調ですね。これは完全に機能しています。ただし、次のようにしてT_PRODUCTテーブルの複合主キーを導入すると、次のようになります。

   static mapping = {
        table 'T_PRODUCT'
        //id column:'PRODUCT_ID'
        id composite:['member', 'productType']
        member column: 'MEMBER_ID'
        productType column: 'PRODUCT_TYPE'
        ...
   }

私はこれを手に入れます:

org.hibernate.StaleStateException:バッチupdaバッチ更新が更新[0]から予期しない行数を返しました。実際の行数:0; 予想:1 org.hibernate.StaleStateException:バッチ更新が更新[0]から予期しない行数を返しました。実際の行数:0; 予想:1 at ProductService.cleanUpGorm(ProductService.groovy:442)at ProductService.maintainProduct(ProductService.groovy:213)at ClientService $ _maintainMembers_closure5.doCall(ClientService.groovy:158)at ClientService.maintainMembers(ClientService.groovy:152)at ClientService.processMembers(ClientService.groovy:394)

私がどこで間違っているのか考えていますか?

4

2 に答える 2

6

Productドメインクラスはメソッドを実装Serializableしてオーバーライドする必要があります。これは、複合キーを使用する状況で実行する必要があります。hashCode()equals()

製品ドメインクラスは次のようになっている必要があります

class Product implements Serializable {
        Long id
        ProductType productType
        ...

        static mapping = {
             table 'T_PRODUCT'
             id composite:['member', 'productType']
             member column: 'MEMBER_ID'
             productType column: 'PRODUCT_TYPE'
        }

        boolean equals(other) {
            if (!(other instanceof Product )) {
                return false
            }
            other.member== member && other.productType== productType
        }

        int hashCode() {
            def builder = new HashCodeBuilder()
            builder.append member
            builder.append productType
            builder.toHashCode()
        }

    }

このようにすべてが大丈夫だと思います。

問題が発生した場合は書き込みます。

于 2012-05-09T12:12:29.683 に答える
1

Grails のドキュメント 5.5.2.5 Composite Primary Keysを読むことを強くお勧めします。彼らは、あなたが尊重しなかった次のことを指摘しています。

  1. 複合主キーでマップされたドメイン クラスは、計算に複合キーのプロパティを使用して、インターフェイスを実装し、メソッドとメソッドSerializableをオーバーライドする必要があります。equals()hashCode()
  2. 複合主キーの使用、特にマップされた列名の関連付けについても注意する必要があります。
  3. おそらく、複合キーで多対 1 のマップ型を使用するのはあまり適切ではありません。

たぶん、正しい方向に進むのに役立ちます。

于 2012-05-08T17:16:00.987 に答える