1

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

Hibernate Version: 4.2.0.Final
MySQL : 5.6.17

The above code generates SQL table like below:

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;

However, I want to generate tables like below:

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

As you can see the cascade code is missing from the hibernate's generated tables. My requirement is to setup One-to-One mapping between Person and Passport. If person data gets deleted then it's associated passport should be deleted as well.

I've tried javax.persistence cascade as well but it didn't work.

Ravi Nain
  • 605
  • 8
  • 16

1 Answers1

3

I believe that in your schema, the Person class is the owning relationship, as evidenced by that you have the mappedBy property on the passport which the person owns. As far as I know, the cascade annotation should be on the owning side of the relationship. However, you currently have it on the passport. Change your Person class to look like this:

@Entity
@Table(name="person")
public class Person {
    ...

    @OneToOne(mappedBy="person")
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
    private Passport passport;
    ...
}

And remove the @Cascade annotatiom from the Passport class.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Hi Tim, your suggestion worked... Isn't it different from normal sql table mapping. Because as we can see in table definition given in question. I added cascade code in passport table(SQL create query). One more thing, still I cannot see cascade code when I export the table schema.... Does hibernate handle it internally? Because I thought it's Database responsibility as it provides such features. – Ravi Nain Sep 21 '16 at 01:44
  • @RaviNain Hibernate does [handle cascades internally](http://stackoverflow.com/questions/19185791/delete-where-cascade-delete-in-hibernate). One reason why you initially put the cascade annotation on the `Passport` class is because in MySQL you would mark this table to be deleted in cascade. But in Hibernate the cascade annotation goes on the owner. – Tim Biegeleisen Sep 21 '16 at 01:49