How can I do bi-directional mapping over @Any annotated property?
In this article http://www.jroller.com/eyallupu/entry/hibernate_the_any_annotation and also in this question How to use Hibernate @Any开发者_JS百科-related annotations?, how @Any annotation can be used was explained. But how can I get borrows for each DVD/VHS/BOOK? How can I do mapping definition on DVD/VHS/BOOK?
I don't think this is supported and, as mentioned in the documentation:
2.4.5.2. @Any
The
@Any
annotation defines a polymorphic association to classes from multiple tables. This type of mapping always requires more than one column. The first column holds the type of the associated entity. The remaining columns hold the identifier. It is impossible to specify a foreign key constraint for this kind of association, so this is most certainly not meant as the usual way of mapping (polymorphic) associations. You should use this only in very special cases (eg. audit logs, user session data, etc).
While I understand that this annotation has been introduced to map an association property to different types of entities that don't have a common ancestor entity, I think it would be better to introduce a base type the other entities would inherit from for bidirectional relations.
See also
- @Any bidirectional relationship fails
Yes, the problem with bi-directional associations where one side is polymorphic (mapped with @Any or @ManyToAny), is that Hibernate auto-generates an invalid foreign key. Personally, I view this as a bug, not a usage error.
You can get around this by specifying the foreign key explicitly, i.e. not rely on Hibernate to infer it. In the Borrow <--> DVD/VHS/Book example, let's say you want a bi-directional, many-to-one association between Borrow and DVD/VHS/Book (the "item"), then you map it on the Borrow side with the polymorphic @Any mechanism to item, and on the item side with a @OneToMany to Borrow.
BUT: on the latter property/getter, you also specify, explicitly, the join column to use, e.g. "ITEM_ID". That should force Hibernate to use only "ITEM_ID", and not (as I've seen) ITEM_ID + ITEM_TYPE that it infers by default from the @Any definition on the other side.
If you don't have a "Item" superclass for DVD/VHS/Book, you'll have to declare this in each class, something like:
@Entity
class Book {
...
@OneToMany
@JoinColumn(name="item_id")
public List<Borrow> getBorrows() {
return this.borrows;
}
}
精彩评论