Search code examples
javahibernateinheritancejpatoplink

JPA Inheritance


Hi I'm new to JPA and I'm having trouble understanding how it handles inheritance.

I have a specific problem I need solved without changing the DB scheme, but if you can't find a solution I would appreciate solution suggestions with a different DB scheme (Hibernate/TopLink solutions welcome).

If I was unclear or you need more information, please tell me so. Thanks in advance!

I have this database:

TABLE Fruit
Id Varchar (10) Primary Key
size Varchar (10)
fruit_type Varchar(10)

TABLE Apple
Id Varchar (10) Primary Key Foreign Key references Fruit.Id
Apple_Property Varchar(10)

So far my entities look like this :

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="fruit_type", discriminatorType=DiscriminatorType.Char)
@DiscriminatorValue(value="fruit")

public class Fruit implements Serializable {

    @Id
    protected String Id;

    protected String size;
}

@Entity
@DiscriminatorValue(value="apple")
//@PrimaryKeyJoinColumn(name="Id" , referencedColumnName="Id")

public class Apple extends Fruit implements Serializable {

    private String Apple_Property;
}

Currently I am able to persist Fruit objects without a problem.. Apple objects persist only when their Fruit object hasn't been persisted yet.

If I try to persist an apple object with an already persisted Fruit object :

Fruit fruit1 = new Fruit("1", "Small");
Apple apple1 = new Apple(fruit1, "red");
provider.create(fruit1);
provider.create(apple1);

I will get an error since JPA tries to create a new row on Fruit table with Id="1" which already exists.

..


Solution

  • When using JPA to persist a child object (i.e provider.create(apple1) in your case) , a record will be inserted to the child table and all of its parent tables. So provider.create(apple1) will insert a record to the Fruit and a record to the Apple table.

    In your example , if you only want to persist an apple object ,just call provider.create(apple1) is enough . It will persist the fruit reference inside the apple object too.

    BTW , I suggest the Fruit Table 's PK to be a number type , and uses @GeneratedValue to mark the ID field of the Fruit bean. In this way , you can let the database to generate an ID for you and no longer need to set it explicitly in the java code to avoid this "ID already exist error" because of setting an already existing ID in the java code.