2010-11-30 3 views
0

私はテストのための簡単なケースを作成しましたが、期待される動作を得られません。 Hibernateは私が(Address.hbm.xml中)多対1の関係に更新=「false」属性を提供しますが、親テーブル(国)を更新することを選択した理由は私が興味を持って?多対1の関係にupdate = "false"が設定されていますが、hibernateが親テーブルの更新を許可するのはなぜですか?

のDDL:

CREATE TABLE Country (
    `id` smallint NOT NULL auto_increment, 
    `name` varchar(100) NOT NULL, 
    PRIMARY KEY (`id`) 
) TYPE=InnoDB AUTO_INCREMENT=0; 
CREATE TABLE Address (
    `id` bigint NOT NULL auto_increment, 
    `firstName` varchar(100) NOT NULL, 
    `lastName` varchar(100) NOT NULL, 
    `countryId` smallint NOT NULL, 
    PRIMARY KEY (`id`), 
    FOREIGN KEY (countryId) 
    REFERENCES Country(id) 
    ON UPDATE CASCADE ON DELETE RESTRICT 
) TYPE=InnoDB AUTO_INCREMENT=0; 

休止XMLS:

<class name="Country" table="Country" lazy="false"> 
    <id name="id" column="id" type="integer"> 
     <generator class="native" /> 
    </id> 
    <property name="name" type="string" not-null="true" length="100"/> 
</class> 
<class name="Address" table="Address" > 
    <id name="id" column="id" type="long" unsaved-value="-1"> 
     <generator class="native" /> 
    </id> 
    <property name="addressFirstName" column="firstName" type="string" not-null="true" length="100"/> 
    <property name="addressLastName" column="lastName" type="string" not-null="true" length="100"/> 
    <!-- Country is parent table, Address is child table (holds the FK countryId). 
     From MySQL: 
     CASCADE: Update the row from the parent table and automatically update the matching rows in the child table. 
     RESTRICT: Rejects the delete operation for the parent table. 
     From hibernate: 
     1. cascade (optional): specifies which operations should be cascaded from the parent object to the associated object. 
     2. update, insert (optional - defaults to true): specifies that the mapped columns should be included in SQL UPDATE 
     and/or INSERT statements. Setting both to false allows a pure "derived" association whose value is initialized 
     from another property that maps to the same column(s), or by a trigger or other application. 
    --> 
    <many-to-one name="country" class="Country" column="countryId" 
     not-null="true" cascade="persist,merge,save-update" update="false" /> 
    <many-to-one name="state" class="State" column="stateId" 
     cascade="persist,merge,save-update" update="false" /> 
</class> 

マイ国テーブル有する一つの行(ID = 1):

INSERT INTO Country (name) VALUES ("United States"); 

Iは、以下のない場合:

Country country = getCountryFrom("US"); 
Address address = new Address(); 
address.setAddressFirstName("Deksa"); 
address.setAddressLastName("Jakim"); 
country.setName("Slovenia"); 
address.setCountry(country); 
address.setId(-1); 
saveAddress(address); 
session.saveOrUpdate(address); 

私はAddressテーブルに1つの新しい行が挿入されていることを期待していますが、Countryテーブル(唯一の行、スロベニアになります)の更新情報も得られます(予想動作< =更新)= "false" を:

Hibernate: select country0_.id as id6_, country0_.name as name6_ from Country country0_ where country0_.stringId='US' 
Hibernate: insert into Address (firstName, lastName, countryId) values (?, ?, ?) 
Hibernate: update Country set name=? where id=? 

、なぜしないように指示された場合、親テーブルを更新休止状態のでしょうか?

敬具、
専制君主

編集:まもなく私はHibernateのカスケードとDBのカスケードを混乱していますし、それはすべての私の問題を解決することを実現し、この記事を書いた後。
ものは以下の通りです:(オプション - 真 デフォルト)を挿入し、

更新:言う明確に休止状態マッピングされた カラムがSQL UPDATE および/またはINSERT文に含まれるべきであることを指定します。 両方をfalseに設定すると、純粋な の値が の が同じ列にマップされる別のプロパティ、または トリガーまたは他のアプリケーションによって初期化される「派生」関連付けが可能になります。

。つまり、countryIdのcountryプロパティでupdate = "false"を使用すると、UPDATEを実行できないと言います(UPDATEはできません)。SET firstName = "x"、lastName = "y"、countryId = 123 countryIdなしでのみ更新を行います。
DBのON UPDATE CASCADEが親テーブル(Country)を参照しています。国が更新されている場合は、子テーブル(AddressテーブルのcountryIdカラム)を更新するよりもです。私がhibernateの更新が行うと思っていたのとは逆に、私はcascade = "save-update"を提供することによって、アドレスオブジェクトのCountryオブジェクトの値がどんな値であっても、それを自分のCountryテーブルで更新すると言います。そこで、解決策は、save-update部分を使わずにcascade = "persist、merge"することでした! country性質上update = "false"を設定

答えて

1

はすなわち、特定のAddressのための別のCountryを選択するために、あなたが対応するcountryIdフィールドを更新することはできません。

既存Countryの名前のchaningを無効にしたい場合は、対応するプロパティにupdate = "false"を指定する必要があります。

<class name="Country" table="Country" lazy="false"> 
    ... 
    <property name="name" type="string" not-null="true" length="100" update = "false" /> 
</class> 
+0

私は国(子オブジェクト)の更新を禁止したい、子供を禁止していませんオブジェクトのプロパティあなたのケースでは、別のクラス(例えば、大陸)がある場合、それは子/メンバーオブジェクトとして国を持ちます、そして、この親クラス(大陸)が国を更新できるようにしたい場合、それは不可能です。言い換えれば、私が望むものではないあらゆるところから国の名前のプロパティの更新を無効にするこの方法だと思います。とにかく返信いただきありがとうございます! – despot

関連する問題