views:

48

answers:

2

I have about 10 different entities in my J2EE application that right now share the exact same implementation. They all inherit from the same generic abstract class that has been annotated as a @MappedSuperclass, but this class contains none of the implementation I have repeated in all the concrete subclasses.

If I could, I'd put all the various fields and collections on this abstract superclass and therefore put the implementation methods there too -- all in one place instead of 10. However, due to JPA restrictions I cannot add JPA annotations to generic fields or accessors.

While I normally favor delegation to implementation inheritance anyway, due to another JPA restriction that says you can't have an embedded entity with a collection the idea of using a delegate also won't work.

When I had only 3-4 of these entities and 2-3 methods, it wasn't a big deal, but now I have about 10 -- and about 7-8 methods each...and some of the methods are getting really complex. And the "cut-copy-paste" inheritance I am using really sucks.

Any other brilliant ideas out there?

+1  A: 
  1. Double-check whether these "restrictions" actually hold true for your JPA provider. I've had embedded objects with collections and it has been fine (with Hibernate). And I've had a @MappedSuperclass with mapped fields.

  2. You can try omitting the @MappedSuperclass, and make the superclass abstract and an @Entity with the proper inheritance hierarchy.

Bozho
1 - have you had a super class with a mapped field that used a generic type parameter like "private List<T> myfield" where "T" is a parameter of the abstract class?
HDave
2 - I've tried that...but your idea makes me wonder if I make the superclass neither an entity, nor mappedsuperclass, nor embedded what would happen. If JPA ignores it, I could potentially used property annotations instead of field annotations on my concrete subclasses that just call super.method() and all reuse the implementation.
HDave
A: 

It turns out you can use either implementation inheritance or delegation as long as you are sure to use property access mode for your JPA annotations. I was using field access mode for JPA annotations and that was causing me no end of suffering because I could not annotate a generic field type.

However with property access mode I simply create my generic abstract implementation without annotating it as an entity, mappedsuperclass, embeddable, or anything. This way JPA will ignore it. Then, in the concrete subclasses, I create protected getter and setters methods as needed and put the JPA annotation on those.

Turned out to be deceptively simple.

HDave