Using hibernate with generics
Solution 1
What you're looking for is probably Hibernate's implicit polymorphism. There's also a little-known "any" relationship which gives complete flexibility, but it has its tradeoffs. You can also use an "any" in a many-to-any.
Edit: I've created a runnable example on Github based around your "Box" class and using an @Any
mapping. You can browse it (or the Box class specifically) or check it out and run it with
git clone git://github.com/zzantozz/testbed tmp
cd tmp
mvn -q compile exec:java -Dexec.mainClass=rds.hibernate.AnyMapping -pl hibernate-any
Solution 2
I've already done that but with subclasses.
Your generic class must be abstract and subclasses must define the generic parameter
Ryan
Updated on June 01, 2022Comments
-
Ryan almost 2 years
I am having some trouble understanding how Hibernate deals with generics and was wondering the best way to accomplish my goal.
Given a simple generic entity:
@Entity public class Box<T>{ private T t; @Id private long id; public void setT(T t) { this.t = t; } public T getT() { return t; } public void setId(long id) { this.id = id; } public long getId() { return id; } }
When going through hibernate initialization, I am getting the exception:
...has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type
I am nearly certain this is because I haven't given hibernate a list of restrictions of what
<T>
can actually be. I know you can specify things such astargetEntity=String.class
abovet
in an annotation, but then you lose the flexibility of having generics. Can I limit the scope of what is an acceptable generic using annotations? For instance: What if I want classesChildA
,ChildB
, whom inherit from an abstract classParent
to be persistable there. In addition, it should also be able to acceptString
s. CanHibernate
deal with such a thing? -
Ryan almost 13 yearsI understand that part, but what about an object type such as
String
that has nothing to do with that inheritance tree. Is that possible to specify additionally? -
Jerome Cance almost 13 yearswhat I want to say is that you can specify generic only if the class which has generic definition is not saved in database as hibernate doesn't know what to save. You can use the targetEntity field to specialize that
-
Ryan almost 13 yearsRyan, is there anywhere online that has a reference to using this type of mapping using generics? I believe have a found a description of what you are referring to here: v4forums.wordpress.com/2008/12/27/… however that example does not seem to satisfy what I want to do. Are you saying I can annotate my generic fields with @any(xxx) with the classes that may be used?
-
Ryan Stewart almost 13 yearsI should've directed you to the newer 3.6 docs. They have more detail. I updated my answer with that link and with a runnable example.
-
Ryan over 12 yearsThank you very much for going through this. Excellent explanation and answer.
-
Ryan over 12 yearsRyan: How would this change if Box also needed a List of <T>'s as well as an object of T?
-
Ryan Stewart over 12 yearsI've never needed or stumbled upon a way to do that. I'm not sure if it's possible. There's an _@Any and a _@ManyToAny, but no _@OneToAny. The complexity of such a mapping might have prevented anyone from ever implementing it. If you think about it--ignoring the generic type constraint as Hibernate would--the content of such a collection could consist of an unlimited number of different types, each specified by a discriminator that would have to live somewhere. It would definitely have to be a relationship using a join table because that's where the discriminators would have to live.
-
Ryan Stewart over 12 yearsThen, in order to load the collection, you'd have to execute a query for each row in the join table, or best case, a query for each distinct discriminator. The results of all such queries would then be aggregated into the collection. See what I meant by complex? I just don't think you're going to find this feature. It feels too expensive and too complicated.
-
Ganesh Satpute about 5 years@RyanStewart when I run it I'm getting similar error
Foreign key (
FKq8tn93chnsr2x9om5wd0vfma6:output [referenced_entity_type,referenced_entity_id])) must have same number of columns as the referenced primary key (stack [id])
. What am I missing?