views:

395

answers:

3

The JPA tutorial states that one can have a non-entity that extends entity class:

Entities may extend both entity and non-entity classes, and non-entity classes may extend entity classes. - http://java.sun.com/javaee/5/docs/tutorial/doc/bnbqa.html

Is it possible to persist such structure?

I want to do this:

@Entity
abstract class Test { ... }

class FirstConcreteTest extends Test { ... } // Non-ntity
class SecondConcreteTest extends Test { ... } // Non-entity

Test test = new FirstConcreteTest();

em.persist(test);

What I would like it to do is to persist all fields mapped on abstract Test to a common database table for all concrete classes (first and second), leaving all fields of first and second test class unpersisted (these can contain stuff like EJBs, jdbc pools, etc).

And a bonus question. Is it possible to persist abstract property too?

@Entity
abstract class Test {

    @Column
    @Access(AccessType.PROPERTY)
    abstract public String getName();

}

class SecondConcreteTest extends Test {
    public String getName() {
        return "Second Concrete Test";
    }
}
+1  A: 

Read that link again. "An entity class must follow these requirements: * The class must be annotated with the javax.persistence.Entity annotation."

If a class is a non-Entity, then it is a non-Entity so is not persisted as an Entity. Anything persistable has to be marked as such, so mark your subclass as an Entity, and mark fields that you don't want to persist as "transient"

DataNucleus
Yeah, but that's exactly what I have been trying to avoid - marking gazillions of concrete test classes with @Entity and it's fields as transient. But that's not all - I need to add @DiscriminatorValue as well (I do have a discriminating column in the DB but with values different than the JPA default). But I start to think it's just illogical. I want only to insert data but the JPA needs to know how to instantiate classes the other way around. Which would probably be impossible in my case. Well at least as long as my superclass is abstract.Anyway, thanks for the answer, DataNucleus.
Michał Minicki
+2  A: 
Pascal Thivent
As I said in the comment to DataNucleus - I wanted to avoid marking concrete classes with @Entity because there are lots of them. And all information that gets persisted is already available through abstract class. Additional annotations on concrete classes add unnecessary clutter and make creating those classes a lot harder (b/c you have to remember to mark fields transient, add @Entity, add discriminating value, etc). I think I'll just stick to Spring's SimpleJdbcInsert there. Thanks, Pascal.
Michał Minicki
+1  A: 

Hi Pascal,

In response to "If you don't want the attributes of the concrete classes to be persisted, mark them all @Transient "

If I am having a field strDecision - either update or delete and I dont want this field to be persisted.

Assume a remote client calls the EJB with this field set. EJB method needs this field for decision making.

When this field is annotated to @Transient in order not to be persisted in the db. During the part of serialization and de-serialization i.e., during the remote call by the client will this field hold the value initialized by the ejb client by the time it reaches EJB.

Naresh S