Reputation: 1685
I have read in several places that you can't use cascade settings on @ManyToOne in hibernate. I am trying to find a way to do this. Let me give you an example:
Assume I have an object called Boxer, and another object called a Fan, who is associated with a Boxer. I want to have my classes set up so the Fan has a reference to the Boxer using @ManyToOne. I don't want to model it like the Boxer has a collection of Fan objects, because there could be millions of them, it would never fit in RAM at runtime.
On the other hand, if a Boxer is deleted from the database, I want my database to also delete all of the Fan rows that referenced that Boxer. I know this can be done in databases using cascade settings, but I can't find a way to have hibernate do that using @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();
}
and here is the boxer code:
@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();
}
here is what hibernate used to create the tables:
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)
As you can see, what I want is the FOREIGN KEY on BOXER_ID to have a cascade setting, and I can't make hibernate do that since I modelled it using @ManyToOne.
Can somebody please tell me how to have hibernate configure cascade settings with @ManyToOne?
Upvotes: 0
Views: 674
Reputation: 1685
In case anybody else is interested, I think the easiest way to make this work is to modify the schema.sql file itself. You can modify the create table statement or alter table statement so the foreign key also says "on delete cascade". You will also need to set the hbm2ddl.auto to validate so hibernate will not go changing your schema for you. The downside is that you will be forced to manually change your database schema, but I think it's worth it. Sooner or later you will realize that hibernate does not make things the most optimal way, and that you should not let hibernate manage your schema.
I have taken classes on hibernate, MySQL, and spring; and I'm considered the hibernate expert on my team, so it might shock you to hear this: The more I work with hibernate, the more I realize how bad and short sighted it is. I keep discovering things it just can't do that MySQL can do. I'm actually thinking seriously of making an alternative to hibernate, if apache gora does not suit my needs. I'm pretty sure that I could make something better.
Upvotes: 1