【问题标题】:Cascade is not working in Hibernate One-to-One mappingCascade 在 Hibernate 一对一映射中不起作用
【发布时间】:2016-09-21 00:53:17
【问题描述】:

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表:

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;

但是,我想生成如下表:

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
);

如您所见,hibernate 生成的表中缺少级联代码。我的要求是设置人员和护照之间的一对一映射。如果个人数据被删除,那么它的相关护照也应该被删除。

我也尝试过 javax.persistence 级联,但没有成功。

【问题讨论】:

    标签: java mysql hibernate jpa hibernate-cascade


    【解决方案1】:

    我相信在您的架构中,Person 类是拥有关系,正如您在该人拥有的护照上拥有 mappedBy 属性所证明的那样。据我所知,级联注释应该在关系的拥有方。但是,您目前在护照上。将您的 Person 类更改为如下所示:

    @Entity
    @Table(name="person")
    public class Person {
        ...
    
        @OneToOne(mappedBy="person")
        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
        private Passport passport;
        ...
    }
    

    并从Passport 类中删除@Cascade 注释。

    【讨论】:

    • 嗨,蒂姆,你的建议奏效了……这和普通的 sql 表映射有什么不同。因为正如我们在问题给出的表定义中看到的那样。我在护照表中添​​加了级联代码(SQL 创建查询)。还有一件事,当我导出表模式时,我仍然看不到级联代码...... hibernate 是否在内部处理它?因为我认为它是数据库的责任,因为它提供了这样的功能。
    • @RaviNain Hibernate 执行handle cascades internally。您最初将级联注释放在Passport 类上的一个原因是,在 MySQL 中,您会将此表标记为在级联中删除。但是在 Hibernate 中,级联注释在所有者身上。
    猜你喜欢
    • 2021-08-18
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多