JPA + Hibernate: How to define a constraint having ON DELETE CASCADE

toytoy picture toytoy · Feb 14, 2013 · Viewed 20.2k times · Source

I am just wondering if there's such a way that I can have build my MySQL table as

ALTER TABLE `USERINFO`
  ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE;

However, I only got this in my DDL when hibernate ++ jpa starts to build my table having "<property name="hibernate.hbm2ddl.auto" value="create" />"

ALTER TABLE `USERINFO` ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`);

In my classes, I have these annotation setup,

// UserAcc.java
@Entity
@Table(name = "USERACC")
public class UserAcc implements Serializable {

private static final long serialVersionUID = -5527566248002296042L;

@Id
@Column(name = "USERID")
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;


@OneToOne(mappedBy = "userAcc")
private UserInfo userInfo;
....


public UserInfo getUserInfo() {
    return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
    this.userInfo = userInfo;
}
...

and,

// UserInfo.java
@Entity
@Table(name = "USERINFO")
public class UserInfo implements Serializable {

private static final long serialVersionUID = 5924361831551833717L;

@Id
@Column(name = "USERINFO_ID", nullable=false)
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userInfoId;

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name="USERID", nullable=false)
@ForeignKey(name = "FK_USER_ID")
private UserAcc userAcc;


public Integer getUserInfoId() {
    return userInfoId;
}

public void setUserInfoId(Integer userInfoId) {
    this.userInfoId = userInfoId;
}
...

Note that, UserAccount table is the parent/main table here while UserInfo is an extended table normalize to another entity. Any answers would be greatly appreciated. I'm just curious how it's done as I love to work also in MySQL. I am just really used to deleting a record from the parent table (USERACOUNT) which would would also allow me to cascade a delete thru child records dependent on the specific record from a parent/primary table.

Thanks!

Answer

Mikko Maunu picture Mikko Maunu · Feb 14, 2013

JPA does offer possibility to cascade operations (merge, persist, refresh, remove) to associated entities. Logic is in JPA and does not utilize database cascades.

@OneToMany(cascade=CascadeType.REMOVE)

There is no JPA standard compliant way to do cascades with database cascades. If such a cascades are preferred, we have to fall back to Hibernate specific construct: @OnDelete. It works with @OneToMany at least, but there used to be some problems in the past with @OneToOne and @OnDelete.

@OnDelete(action = OnDeleteAction.CASCADE)

Be aware that adding this annotation to an existing constraint will not update it. You may have to manually drop it first to properly update the schema.