Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle JPA annotations for a pointer to a generic interface

I have a generic class that is also a mapped super class that has a private field that holds a pointer to another object of the same type:

@MappedSuperclass
public abstract class MyClass<T extends MyIfc<T>>
    implements MyIfc<T>
    {

        @OneToOne()
        @JoinColumn(name = "previous", nullable = true)
        private T previous;

             ...
             }

My problem is that Eclipse is showing an error in the file at the OneToOne "Target Entity "T" for previous is not an Entity." All of the implementations of MyIfc are, in fact, Entities. I should also add that each concrete implementation that inherit from MyClass uses a different value for T (because T is itself) so I can't use the "targetEntity" attribute.

I guess if there is no answer then I'll have to move this JPA annotation to all the concrete subclasses of MyClass. It just seems like JPA/Hibernate should be smart enough to know it'll all work out at run-time. Makes me wonder if I should just ignore this error somehow.

like image 862
HDave Avatar asked May 11 '10 05:05

HDave


People also ask

Which annotation in JPA is used to customize the mapping of a field?

@Column. Let's start with the @Column annotation. It is an optional annotation that enables you to customize the mapping between the entity attribute and the database column.

Which JPA annotation can be used to map the class field to a DB column?

The @Basic annotation is used to map a basic attribute type to a database column.

How do I ignore a table column in JPA entity?

To exclude the id attribute, the @MapsId annotation will tell Hibernate that the post association takes care of the table Primary Key column value. So, when the entity identifier and an association share the same column, you can use @MapsId to ignore the entity identifier attribute and use the association instead.


Video Answer


2 Answers

My problem is that Eclipse is showing an error in the file at the OneToOne "Target Entity "T" for previous is not an Entity."

Yes, and even if T was extending an Entity, I am not aware of any JPA provider supporting this (that's just not part of the JPA spec anyway). For more feedback have a look at JPA Generic entities classes Mappedsuperclass are not possible! (very similar thread about EclipseLink):

No you will be unable to make the Entities generic. The provider will be unable to map the relationship to the specific type defined by the generic definition as this type is assigned when the Entity is created in code not where the Entity is defined. Remember when designating Generics the Collection (in this case) is limited only to those types. The Provider can not possibly be this restrictive on a per Entity instance basis. In some cases changing the type may result in entirely different tables being mapped for a single Entity instance and that is definitely not supported.

like image 104
Pascal Thivent Avatar answered Oct 17 '22 08:10

Pascal Thivent


Since JDO supports persistence of interface fields (which is a similar concept to what you have here), and since DataNucleus JPA is built on top of the JDO capabilities, then it likely would allow you to persist such a field (I have an example using JDO that does something very similar, but without seeing the remains of your classes and persistence code its impossible to be definitive). Give it a try and see what happens.

Obviously that is beyond the JPA spec, hence if portability is a concern for you then have a think first

like image 2
DataNucleus Avatar answered Oct 17 '22 06:10

DataNucleus