Hibernate @ManyToOne和级联

时间:2014-05-11 16:54:14

标签: hibernate cascade

我在几个地方读到你不能在hibernate中使用@ManyToOne上的级联设置。我正试图找到一种方法来做到这一点。让我举个例子:

假设我有一个名为Boxer的对象,以及另一个名为Fan的对象,它与Boxer相关联。我想设置我的课程,以便Fan使用@ManyToOne引用Boxer。我不想像Boxer那样对它进行建模,因为它可能有数百万个,在运行时它永远不会适合RAM。

另一方面,如果从数据库中删除Boxer,我希望我的数据库也删除引用该Boxer的所有Fan行。我知道这可以在使用级联设置的数据库中完成,但是我找不到让hibernate使用@ManyToOne做到这一点的方法。

@Entity
@Table(name="FAN")
public class Fan extends Person {
    private Boxer favoriteBoxer;

    // hibernate is ignoring all of these cascade settings
    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="BOXER_ID",nullable=false)
    @Cascade(value={org.hibernate.annotations.CascadeType.ALL})
    public Boxer getFavoriteBoxer() {
        return favoriteBoxer;
    }

    @Id
    @Column(name="FAN_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)
    public long getId() {
        return super.getId();
    }

    @Column(name="NAME")
    public String getName() {
        return super.getName();
    }

这是拳击手代码:

@Entity
@Table(name="BOXER")
public class Boxer extends Person {
    private int weight;
    private int height;

    @Column(name="WEIGHT")
    public int getWeight() {
        return weight;
    }

    @Column(name="HEIGHT")
    public int getHeight() {
        return height;
    }

    @Id
    @Column(name="BOXER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)
    public long getId() {
        return super.getId();
    }

    @Column(name="NAME",unique=true)
    public String getName() {
        return super.getName();
    }

这是用于创建表的hibernate:

mysql> show create table BOXER\G
*************************** 1. row ***************************
       Table: BOXER
Create Table: CREATE TABLE `BOXER` (
  `BOXER_ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `HEIGHT` int(11) DEFAULT NULL,
  `NAME` varchar(255) DEFAULT NULL,
  `WEIGHT` int(11) DEFAULT NULL,
  PRIMARY KEY (`BOXER_ID`),
  UNIQUE KEY `UK_iwqngmn7h1s95cvtn9twuwybs` (`NAME`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> show create table FAN\G
*************************** 1. row ***************************
       Table: FAN
Create Table: CREATE TABLE `FAN` (
  `FAN_ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(255) DEFAULT NULL,
  `BOXER_ID` bigint(20) NOT NULL,
  PRIMARY KEY (`FAN_ID`),
  KEY `FK_3oelgvwo3en8m0j1kng75n7w7` (`BOXER_ID`),
  CONSTRAINT `FK_3oelgvwo3en8m0j1kng75n7w7` FOREIGN KEY (`BOXER_ID`) REFERENCES `BOXER` (`BOXER_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

正如你所看到的,我想要的是BOXER_ID上的FOREIGN KEY有一个级联设置,我不能让hibernate这样做,因为我用@ManyToOne建模它。

有人可以告诉我如何使用@ManyToOne进行hibernate配置级联设置吗?

1 个答案:

答案 0 :(得分:0)

如果有其他人感兴趣,我认为最简单的方法是修改schema.sql文件本身。您可以修改create table语句或alter table语句,以便外键也显示“on delete cascade”。您还需要设置hbm2ddl.auto以进行验证,以便hibernate不会为您更改架构。缺点是您将被迫手动更改数据库架构,但我认为这是值得的。迟早你会意识到hibernate不会使事情成为最佳方式,你不应该让hibernate管理你的架构。

我参加过hibernate,MySQL和spring课程;而且我被认为是我团队中的hibernate专家,所以听到这个可能会让你感到震惊:我越是使用hibernate,我越觉得它有多么糟糕和短视。我一直在发现MySQL无法做到的事情。如果apache gora不适合我的需要,我实际上正在认真考虑替代hibernate。我很确定我能做得更好。