Cascade 在 Hibernate 一对一映射中不起作用
Cascade is not working in Hibernate One-to-One mapping
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
上面的代码生成 SQL table 如下所示:
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;
但是,我想生成如下所示的 tables:
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
);
如您所见,休眠生成的 table 中缺少级联代码。我的要求是在 Person 和 Passport 之间设置一对一映射。如果个人数据被删除,那么它的相关护照也应该被删除。
我也试过 javax.persistence 级联,但没用。
我相信在你的架构中,Person
class 是拥有关系,证明你的护照上有 mappedBy
属性人拥有。据我所知,级联注释应该在关系的拥有方。但是,您目前在护照上有它。将您的 Person
class 更改为如下所示:
@Entity
@Table(name="person")
public class Person {
...
@OneToOne(mappedBy="person")
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
private Passport passport;
...
}
并从 Passport
class 中删除 @Cascade
注释。
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
上面的代码生成 SQL table 如下所示:
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;
但是,我想生成如下所示的 tables:
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
);
如您所见,休眠生成的 table 中缺少级联代码。我的要求是在 Person 和 Passport 之间设置一对一映射。如果个人数据被删除,那么它的相关护照也应该被删除。
我也试过 javax.persistence 级联,但没用。
我相信在你的架构中,Person
class 是拥有关系,证明你的护照上有 mappedBy
属性人拥有。据我所知,级联注释应该在关系的拥有方。但是,您目前在护照上有它。将您的 Person
class 更改为如下所示:
@Entity
@Table(name="person")
public class Person {
...
@OneToOne(mappedBy="person")
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
private Passport passport;
...
}
并从 Passport
class 中删除 @Cascade
注释。