2016-09-21 13 views
0

Person.javaは、カスケードは休止状態で動作していない一対一のマッピング

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.OneToOne; 
import javax.persistence.Table; 

@Entity 
@Table(name="person") 
public class Person { 

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private int id; 

@Column(name="name") 
private String name; 

@Column(name="age") 
private int age; 

@OneToOne(mappedBy="person") 
private Passport passport; 

----getter and setter---- 

Passport.java

import java.util.Date; 

import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.OneToOne; 

import org.hibernate.annotations.Cascade; 
import org.hibernate.annotations.CascadeType; 

@Entity 
public class Passport { 

@Id 
private String passportNumber; 
private Date issuedDate; 
private Date expiryDate; 
private String issuedPlace; 
private String nationality; 

@OneToOne 
@Cascade(value={CascadeType.DELETE}) 
@JoinColumn(name="frn_person_id", unique=true, referencedColumnName="id") 
private Person person; 

---getter setter---- 

休止バージョン:4.2.0.Final
MySQL:5.6.17

Thコード上記eは以下のようなSQLテーブルを生成します。あなたはカスケードコードが休止状態の生成テーブルから欠落して見ることができるように

create table jaydb.person(
    id integer auto_increment primary key, 
    name varchar(100) unique, 
    age integer 
); 

create table jaydb.passport(
    passport_number varchar(50) primary key, 
    issued_date date, 
    expiry_date date, 
    issued_place varchar(100), 
    nationality varchar(100), 
    frn_person_id integer unique, 
    foreign key(p_id) 
    references jaydb.person(p_id) 
    on delete cascade 
    on update cascade 
); 

CREATE TABLE `person` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `age` int(11) DEFAULT NULL, 
    `name` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; 

CREATE TABLE `passport` (
    `passportNumber` varchar(255) NOT NULL, 
    `expiryDate` datetime DEFAULT NULL, 
    `issuedDate` datetime DEFAULT NULL, 
    `issuedPlace` varchar(255) DEFAULT NULL, 
    `nationality` varchar(255) DEFAULT NULL, 
    `frn_person_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`passportNumber`), 
    KEY `FK4C60F032382EC083` (`frn_person_id`), 
    CONSTRAINT `FK4C60F032382EC083` FOREIGN KEY (`frn_person_id`) REFERENCES `person` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

はしかし、私は以下のようなテーブルを生成します。私の要件は、PersonとPassportの間の一対一マッピングを設定することです。人のデータが削除されると、関連するパスポートも削除する必要があります。

私もjavax.persistenceカスケードを試しましたが、動作しませんでした。

答えて

3

あなたのスキーマでは、Personクラスはオーナーが所有するパスポートにmappedByというプロパティがあることから明らかです。私が知る限り、カスケード注釈は関係の所有側にあるべきです。しかし、現在あなたはパスポートにそれを持っています。

@Entity 
@Table(name="person") 
public class Person { 
    ... 

    @OneToOne(mappedBy="person") 
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE}) 
    private Passport passport; 
    ... 
} 

そしてPassportクラスから@Cascade annotatiomを削除:あなたのPersonクラスは次のように見えるように変更します。

+0

こんにちはティム、あなたの提案は働いた... これは、通常のSQLのテーブルのマッピングとは異なりますか?なぜなら、問題のテーブル定義で見ることができるからです。パスポートテーブルにカスケードコードを追加しました(SQL作成クエリ)。 テーブルスキーマをエクスポートするともう1つ、カスケードコードが表示されません....内部的にHibernateを処理しますか?そのような機能を提供するのはデータベースの責任だと思ったからです。 –

+0

@RaviNain Hibernateは[内部でカスケードを処理します](http://stackoverflow.com/questions/19185791/delete-where-cascade-delete-in-hibernate)。最初にカスケードアノテーションを 'Passport'クラスに置く理由の1つは、MySQLではこのテーブルをカスケードで削除するようにマークするためです。しかし、Hibernateでは、カスケードアノテーションは所有者に行きます。 –

関連する問題