tags:

views:

81

answers:

1

Dynamic Inheritance

I have a situation where I want a class (which is a JPA entity) to be able to extend either class A or class B dynamically. My thought was to use Generics, but it looks like generics doesn’t support this. For example:


@Entity
public abstract class Resource() {
...
}

@Entity
public abstract class Snapshot() {
...
}

public abstract class CommonRS<R extends Resource, S extends Snapshot> {
/* This is the class that I want to dynamically assign Inheritance to. */
...
}

@Entity
public class FeedResource extends CommonRS<Resource> {
...
}

@Entity
public class FeedSnapshot extends CommonRS<Snapshot> {
...
}

The reason I want to do this is that FeedResource must Inherit from Resource and FeedSnapshot must inherit from Snapshot because both classes are using the JPA join strategy InheritanceType.JOINED and are persisted to different tables, however they both share common attributes and I would like them to be able to inherit those common attributes.

I understand that I can I could use @Embeddable on CommonRS and the Embed it in both FeedResource and FeedSnapshot.

Since Java doesn’t support multiple inheritance, I can’t see any other way to do this other than using Embeddable.

Thanks in advance.

+2  A: 

Here is how you do it

@MappedSuperClass
public abstract class Base() {
...
// put your common attributes here
}

@Entity
public abstract class Resource() extends Base{
...
}

@Entity
public abstract class Snapshot() extends Base {
...
}

public abstract class CommonRS<R extends Base> {
...
}

@Entity
public class FeedResource extends CommonRS<Resource> {
...
}

@Entity
public class FeedSnapshot extends CommonRS<Snapshot> {
...
}

UPDATE

Another solution can be implementing same interface (if common inheritance cannot be achieved). In that case @MappedSuperClass annotation should be used on actual base classes.

@Entity
public abstract class Resource() extends BaseIntf {
...
}

@Entity
public abstract class Snapshot() extends BaseIntf {
...
}

public abstract class CommonRS<R extends BaseIntf> {
...
}

@Entity
public class FeedResource extends CommonRS<Resource> {
...
}

@Entity
public class FeedSnapshot extends CommonRS<Snapshot> {
...
}
eugener
Thank you. One thing I forgot to mention in my example above is that Resource and Snapshot can't extend "Base" as there are many "Bases" that they may have to extends. That's why I was hoping to have CommonRS dynamically extend whatever "Base" I needed to.I coming to the conclusion the only way to do it is by using Embeddable.
DKD
Try to implement the same interface instead of extending Base class. Should work the same way
eugener
See the updated answer
eugener