0

に入れるinverse=trueset、何も削除されません。そうしないと、 から削除するMealIngredientset、Hibernate は を設定しようとしnullますが、失敗し、例外がスローされます。

[SQLITE_CONSTRAINT]  Abort due to constraint violation (MealIngredients.mealId may not be NULL)

XML マッピングは次のとおりです。

<class name="restaurant.meal.Meal" table="Meals">
    <id name="id" type="integer">
        <column name="id" not-null="true" unique="true"/>
        <generator class="increment"/>
    </id>
    <!-- some other, simple properties -->

    <set name="ingredientsSet" cascade="all" lazy="false">
        <key>
            <column name="mealId" not-null="true" />
        </key>
        <one-to-many class="restaurant.meal.MealIngredient" />
    </set>
</class>

<class name="restaurant.meal.MealIngredient" table="MealIngredients">
    <composite-id name="id" class="restaurant.meal.MealIngredient$Id">
        <key-property name="ingredientId" />
        <key-property name="mealId" />
    </composite-id>
    <many-to-one name="ingredient" class="restaurant.storage.Ingredient" insert="false" update="false" lazy="false">
        <column name="ingredientId" not-null="true" />
    </many-to-one>
    <many-to-one name="meal" class="restaurant.meal.Meal" insert="false" update="false" lazy="false">
        <column name="mealId" not-null="true" />
    </many-to-one>
    <!-- other properties -->
</class>

Mealはい、との関係はIngredient結合テーブルを使用した多対多です (そして、そのテーブルに追加の列があるため、同様MealIngredientにマップする必要があります)。MealIngredient

この質問は私を助けませんでし

編集:挿入のみが現在のマッピングで機能し、更新はMealIngredientテーブルに別の行を生成するだけです。


編集2: hashCodeおよびequals実装:

MealIngredient$Id : (Apache commons-lang EqualsBuilderおよびHashCodeBuilderを使用)

@Override
public boolean equals(Object o) {
    if(!(o instanceof Id))
        return false;

    Id other = (Id) o;
    return new EqualsBuilder()
               .append(this.getMealId(), other.getMealId())
               .append(this.getIngredientId(), other.getIngredientId())
               .isEquals();
}

@Override
public int hashCode() {
    return new HashCodeBuilder()
               .append(this.getMealId())
               .append(this.getIngredientId())
               .hashCode();
}

食事成分:

@Override
public boolean equals(Object o)
{
    if(!(o instanceof MealIngredient))
        return false;

    MealIngredient other = (MealIngredient) o;
    return this.getId().equals(other.getId());
}

@Override
public int hashCode()
{
    return this.getId().hashCode();
}

ログを確認しましたが、Hibernate が内部で何をしているのかはわかりませんが、次のようにinsertなりMealIngredientます。

15:42:53,122 TRACE IntegerType:172 - returning '5' as column: quantity3_
Hibernate: 
    insert 
    into
        MealIngredients
        (quantity, ingredientId, mealId) 
    values
        (?, ?, ?)
15:42:53,131 TRACE IntegerType:133 - binding '16' to parameter: 1
15:42:53,131 TRACE IntegerType:133 - binding '5' to parameter: 2
15:42:53,131 TRACE IntegerType:133 - binding '1' to parameter: 3

MealIngredientそして、から削除するとMeal.ingredientsSet、Hibernate は次updateのように設定しようとしmealIdますnull

Hibernate: 
    update
        MealIngredients 
    set
        quantity=? 
    where
        ingredientId=? 
        and mealId=?
15:48:57,529 TRACE IntegerType:126 - binding null to parameter: 1
15:48:57,529 TRACE IntegerType:133 - binding '1' to parameter: 2
15:48:57,531 TRACE IntegerType:133 - binding '1' to parameter: 3
15:48:57,535  WARN JDBCExceptionReporter:77 - SQL Error: 0, SQLState: null
15:48:57,535 ERROR JDBCExceptionReporter:78 - [SQLITE_CONSTRAINT]  Abort due to constraint violation (MealIngredients.quantity may not be NULL)
4

2 に答える 2

0

あなたが探している説明はここにあると思います。そうですね。彼の説明を読まないでください、それは私を混乱させます。しかし、彼の例は優れています。

とにかく、次のいずれかを行いたいと思います。

inverse=false食材コレクションからmealIngredientを削除し、食事を保存します

inverse=trueMealIngredient の食事インスタンス変数を null にして、MealIngredient を保存する必要があります

編集:更新ではなく挿入の問題は、おそらくハッシュコードと等号をオーバーライドしていないことが原因です。Eclipse を使用している場合は、Eclipse で実行できると思いますが、メソッドを自動生成するときに複合キーの両方のプロパティを使用するように指示する必要があります。Hibernateのドキュメントの第5章ごと:

永続クラスは、equals() および hashCode() をオーバーライドして、複合識別子の等価性を実装する必要があります。また、Serializable も実装する必要があります。

于 2013-04-26T23:12:28.777 に答える