Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate/JPA Mapping on abstract class

What would be the best practice to implement the following situation with Hibernate.

We define an abstract class that will form the base of any object that we want to persist in our database. It contains the id etc etc...

public abstract class ModelObject {
    protected int id;

    ...
}

Now we subclass our base clase for special cases where more than one entity will have a similar fields.

public abstract class ModelObjectWithNose extends ModelObject {
    ...
    protected Nose nose;
}

Now, for all classes that we want to have a Nose:

public class Person extends ModelObjectWithNose { ... }

public class Animal extends ModelObjectWithNose { ... }

The real problem we have at the moment now is that this relationship needs to be bi-directional. Each concrete class needs to know which Nose is theirs, but each Nose also needs to know to what object it belongs.

public class Nose {
    ...
    private ModelObjectWithNose owner;
}

For our example we need a @OneToOne relationship, as each Person can only have one Nose and each Nose can only belong to one Person.

What we have tried is doing the following:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class ModelObjectWithNose extend ModelObject { ... }

and then:

@Entity
public class Person extends ModelObjectWithNose { ... }

...etc etc etc.

1) How do I define the relationship between the Nose and the ModelObjectWithNose? Is it as simple as:

@Entity
public class Nose {
    ...
    // this causes: 'Basic' attribute should not be 'Persistence Entity' 
    ModelObjectWithNose owner;
}

2) Is there a better / more preferred way? Would the inheritance strategy work properly?

Thanks!

EDIT

So I have tried a few ways which all seem to potentially work. Using any of the three Inheritance schemes works fine if you set up the annotations as in the question. Unfortunately this has a huge impact on our existing database and code, so we opted to (for now) simply index the Nose object's id field that is kept on our current objects that would have extended ModelObjectWithNose and simply write helper methods to do point queries to find the entries.

like image 214
Nico Huysamen Avatar asked Nov 15 '22 02:11

Nico Huysamen


1 Answers

Annotate your Nose property in ModelObjectWithNose as @OneToOne and in the Nose entity you do the same with ModelObjectWithNose owner. Set the mappedBy attribute of the annotation of the Nose entity, so JPA knows on which table the FK should be inserted (In your model the ModelObjectWithNose should have the FK to Nose, not other way around. You set it on the inverse end of the one-to-one relationship, ie. the one that has the PK to use.)

BTW your Entities must implement Serializable (you can do so on the ModelObject class to enforce it on inheriting classes). The id property of ModelObject should be annotated as @Id.

Cheers, Kai

like image 183
Kai Avatar answered Dec 15 '22 01:12

Kai