Share it now!

THERE IS A NEW VERSION OF THIS POST.
CLICK HERE: http://uaihebert.com/?p=1674&page=14

Hello, how are you?

Let us talk today about how to create a database table per subclass of your hierarchy; each table will have only the data of its class. In the last post we had seen how to persist all hierarchy in one table.

I will use the same code from the last post but with the code already edited.

In the end of this post, you will find the source code of the application.

In the following links you can find the last post about this subject and the others post about JPA: JPA Single Table per Class Hierarchy, @ManyToMany Unidirectional and Bidirectional, @OneToMany and @ManyToOne Unidirectional and Bidirectional, OneToOne Unidirectional and Bidirectional, Mapping two Tables in one Class, Mapping Date and Enum, Composite Primary-Key, SequenceGenerator, TableGenerator – Simple Primay Key, Auto Create Schema Script with: Ant, Hibernate 3 and JPA 2, Tutorial Hibernate 3 with JPA 2.

Take a look and see how the code has to be:

package com.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

@Entity
@Table(name="CAR")
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Car {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
package com.model;

import javax.persistence.Entity;

@Entity
public class Beetle extends Car {
    private int gasCapacity;

    public void talk(){
        System.out.println("Herbie!");
    }

    public int getGasCapacity() {
        return gasCapacity;
    }

    public void setGasCapacity(int gasCapacity) {
        this.gasCapacity = gasCapacity;
    }
}
package com.model;

import javax.persistence.Entity;

@Entity
public class Ferrari extends Car {
    private int model;

    // The newest new models will fly... some day! =P
    public void fly() {

    }

    public int getModel() {
        return model;
    }

    public void setModel(int model) {
        this.model = model;
    }
}

After we run the Main class let us take a look and see how our tables will look like:

Now each table has the data of its respective class.

I would like to call your attention to a situation.

Notice that every class of our hierarchy has the id with the same name “id”. If your subclass has a different id attribute name, you will have to map this with a different annotation.

Imagine that the Beetle class has its table id named as “beetleId”; we need to add an annotation in the Beetle class:

package com.model;

import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;

@Entity
@PrimaryKeyJoinColumn(name="beetleId")
public class Beetle extends Car {

    private int gasCapacity;

    public void talk() {
        System.out.println("Herbie!");
    }

    public int getGasCapacity() {
        return gasCapacity;
    }

    public void setGasCapacity(int gasCapacity) {
        this.gasCapacity = gasCapacity;
    }
}


Notice that the primary key now has a different name than Car and Ferrari.

Remember this: if your subclass id field has a name that is not the same of your super class, you will need to use the @PrimaryKeyJoinColumn annotation; the “name” parameter indicates which column will be mapped. If you need to set up the Super Class id column you can use the parameter: “referencedColumnName”.

Let us see now the advantages and the disadvantages of this approach:

  • Advantage: You will be able to have null attributes in your subclasses; you would not be able to do this if you use the one table for all hierarchy strategy. There is a good sql performance over the next pattern that we will see: “One table with all fields per Subclasses”. In the book “Enterprise JavaBens 3.0” the author says that this approach is better than “One table with all fields per Subclasses” only if the database SQL Union is not supported by your database.
  • Disadvantage: It has a lower performance than “One table to all hierarchy strategy”.

Click here to download the source code of this post. Just do not forget to change the user/password.

I hope this post may help you.

If you have any comments/questions just post it.

See you later! \o_