comment 0

Hibernateをいじる(7)

続いて、DELETEをやります。

まず、今回のサンプルのおさらいをしておきます。

Hibernateをいじる(2)

Study(履修)は、Student(学生)とSubject(科目)のそれぞれを1つ持ち(Studyから見てmany-to-one)、Report(レポート)とExamination(試験)のそれぞれを複数持ちます(Studyから見てone-to-many)。

1.単純にdelete()を使う

[java]
//まず削除したいオブジェクトを取得。
Query query = session.createQuery(“FROM Study AS study WHERE study.student.gakusekiNo=~ AND study.subject.code=~”);
query.setString(0, “0499001”);
query.setString(1, “14501”);
Study study = (Study)query.uniqueResult();

//いざ削除。
session.delete(study);
[/java]

簡単ですね。

今回のサンプルでは、Study.hbm.xmlで、ReportとExaminationに対してcascade=”all”が指定されています。

そのため、削除したStudyの配下にあるReportとExaminationはDBから削除されます。

もし、cascade=”none”で、DBで参照制約をかけていると、当然にエラーになります。この辺は、Hibernateだからどうこう…ではないようです。

例をもう1つ。

[java]
Study study = (Study)query.uniqueResult();

//2つ目を削除
Report report = (Report)study.getReports().get(1);

//リストから消して…
study.getReports().remove(report);

//子をDELETE
session.delete(report);
[/java]

このように、親子関係のある子だけを削除する場合、先に親が持つ子のリストから、削除したい子を消しておく必要があります。

いきなり、子だけのsession.delete()をやってしまうと、エラーになります。

2.delete()を使わなくても削除できるケース

どんなケースかというと、親が持つ子のリストから、子を消して、親をupdate()するケースです。

実例を見ましょう。

[java]
Study study = (Study)query.uniqueResult();

//2つ目を削除
Report report = (Report)study.getReports().get(1);

//リストから消して…
study.getReports().remove(report);

//親をUPDATE
session.saveOrUpdate(study);
[/java]

親であるstudyが持つ子のリスト(getReports()で取れるList)から、子のreportをremove()して、親のstudyをsaveOrUpdate()しています。

そうすると、リストから削除された子が消えます。

但し、要注意点が1つ。

このようなプログラムで、期待する挙動(リストから削除した子オブジェクトがDBからもDELETEされている)にするためには、Study.hbm.xmlで、cascade=”all-delete-orphan”にしなくてはなりません。

そのように設定しなければ、子オブジェクトはDBに残り、その外部KEYカラムがnullとしてUPDATEされるだけです。

Follow me!

Filed under: ブログ

About the Author

Posted by

経済産業省推進資格ITコーディネータ/ITエンジニア。井上研一事務所代表、株式会社ビビンコ代表取締役。北九州市出身、横浜市在住。 2000年よりプログラマ・SEとして企業の業務システム開発に従事し、2012年に独立。AIやIoTに強いITコーディネータとしても活動中。著書に「初めてのWatson」、「ワトソンで体感する人工知能」など。セミナーや研修講師での登壇も多数。

コメントを残す