I want to persist my litte zoo with开发者_开发知识库 Hibernate:
@Entity
@Table(name = "zoo")
public class Zoo {
@OneToMany
private Set<Animal> animals = new HashSet<Animal>();
}
// Just a marker interface
public interface Animal {
}
@Entity
@Table(name = "dog")
public class Dog implements Animal {
// ID and other properties
}
@Entity
@Table(name = "cat")
public class Cat implements Animal {
// ID and other properties
}
When I try to persist the zoo, Hibernate complains:
Use of @OneToMany or @ManyToMany targeting an unmapped class: blubb.Zoo.animals[blubb.Animal]
I know about the targetEntity
-property of @OneToMany
but that would mean, only Dogs OR Cats can live in my zoo.
Is there any way to persist a collection of an interface, which has several implementations, with Hibernate?
JPA annotations are not supported on interfaces. From Java Persistence with Hibernate (p.210):
Note that the JPA specification doesn’t support any mapping annotation on an interface! This will be resolved in a future version of the specification; when you read this book, it will probably be possible with Hibernate Annotations.
A possible solution would be to use an abstract Entity with a TABLE_PER_CLASS
inheritance strategy (because you can't use a mapped superclass - which is not an entity - in associations). Something like this:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractAnimal {
@Id @GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
...
}
@Entity
public class Lion extends AbstractAnimal implements Animal {
...
}
@Entity
public class Tiger extends AbstractAnimal implements Animal {
...
}
@Entity
public class Zoo {
@Id @GeneratedValue
private Long id;
@OneToMany(targetEntity = AbstractAnimal.class)
private Set<Animal> animals = new HashSet<Animal>();
...
}
But there is not much advantages in keeping the interface IMO (and actually, I think persistent classes should be concrete).
References
- Annotations, inheritance and interfaces
- using MappedSuperclass in relation one to many
- Polymorphic association to a MappedSuperclass throws exception
I can guess that what you want is mapping of inheritance tree. @Inheritance annotation is the way to go. I don't know if it will work with interfaces, but it will definitely work with abstract classes.
I think you have to annotate the interface too with @Entity
and we have to annotate @Transient
on all getters and setters of interface.
精彩评论