[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-4233?page=c...
]
Darren Kelly edited comment on HHH-4233 at 11/28/11 3:02 AM:
-------------------------------------------------------------
I would like to confirm that this feature also works in EclipseLink (and in OpenJPA as
observed above), and want to like others above make the case for support, instead of
rejection, of this feature. I wanted to compare Hibernate with other JPA providers with my
code, but I can't because Hibernate does not support this important feature, and make
the strong case here that it should.
I have read very carefully through Emmanuel's arguments against this feature above,
and I do not agree with them.
For what it's worth, I am a UML expert (I even worked as an expert consultant to a UML
tool vendor), and I teach UML. In UML there is the ability to redefine a Property in the
context of a subclass, and that is exactly what is going on here. One can have an
bi-directional Association with that _redefined_ Property as one Association end.
In the example given Nino above, one can have an Association between Person and Cat, where
the _redefined_ Property 'owner' is at one end of the Association. It is not a
"Frankenstein" association at all.
It is simply not true that: "You are doing a bidirectional relationship but the types
are different." One can construct any number of bi-directional relationships to
different subclasses, and each one can target a different _redefined_ owner Property at
one end.
Emmanuel wrote: "Try and represent your model with the bidirectional association (and
not two different associations) into UML and you will see you cannot."
The notion that it is somehow a triangular relationship is incorrect. The relationship
from say Person to Cat need not go to Mammal at all, and the relationship from the
'owner' Property that is inherited into Cat from Mammal does not come from Mammal.
There is no triangle (if you do it right).
The "triangle" that Emmanuel is describing would have on one side a
uni-directional Association from 'owner' in the base class Mammal to Person, and
it would have to preempt the existence of the various lists (say) of Cats, Dogs, whatever
in Person. But the relationship described in the example from Nino does not do that,
because it is acting on the 'owner' Property as redefined in Cat, and this is made
clear by the fact that the List in Person is a list of Cat. It is acting on the Cat type,
not the Mammal type. There is no triangle.
And this is also wrong, or at least not the point: "I can write code that associates
a Dog to a Person and get it loaded as a Cat." This is ignoring the fact that the
'owner' Property that is inherited into each subclass may in fact be uniquely
redefined.
I can happily have a nice clean bi-directional relationship from Person to Cat's
owner, from Person to a Dog's owner, and so on. Each one is a separate relationship,
and each one can be mapped by 'owner', and that is exactly what EclipseLink (and
presumably OpenJPA) does.
Finally I present a rather abstract example from my own code, but it makes the point well.
In my system there is a concept of a Parsel ("parsing element"), which is an
element that represents a sentence or phrase of text that can be decomposed into various
elements, which are said to be "involved in" a Parsel, and one can involve all
instances of named properties of different kinds in a Parsel at once, using different
kinds of "property involvers"
@Entity
public class AbstractPropertyInvolver extends All_ implements Serializable {
private Parsel owner;
@ManyToOne
/** The owner (a.k.a. parent) of this property involver.
* Properties will be considered involved in this.
*/
public Parsel getOwner() {
return owner;
}
public void setOwner(Parsel owner) {
this.owner = owner;
}
---
Now there are 2 main subclasses of AbstractPropertyInvolver, a basic PropertyInvolver that
is for handling Block properties and Value properties (where a Block is a systems
engineering block), and a ListelPropertyInvolver, where a Listel is a deep List wrapper
object. Both PropertyInvolver and ListelPropertyInvolver inherit
AbstractPropertyInvolver's 'owner' definition, but they are completely free to
_redefine_ the 'owner' Property (in UML sense) and have it participate in
different relationships.
So at the Parsel end:
private List<PropertyInvolver> valueInvolvers = new
ArrayList<PropertyInvolver>();
@OneToMany(mappedBy = "owner",
cascade = CascadeType.ALL)
@ExpertProperty
public List<PropertyInvolver> getValueInvolvers() {
return valueInvolvers;
}
public void setValueInvolvers(List<PropertyInvolver> valueInvolvers) {
this.valueInvolvers = valueInvolvers;
}
private List<PropertyInvolver> blockInvolvers = new
ArrayList<PropertyInvolver>();
@OneToMany(mappedBy = "owner",
cascade = CascadeType.ALL)
public List<PropertyInvolver> getBlockInvolvers() {
return blockInvolvers;
}
private List<ListelValueInvolver> listelValueInvolvers = new
ArrayList<ListelValueInvolver>();
@OneToMany(mappedBy = "owner",
cascade = CascadeType.ALL)
public List<ListelValueInvolver> getListelValueInvolvers() {
return listelValueInvolvers;
}
These represent unique bi-directional relationships. Note also that the 'owner' of
PropertyInvolver is the mappedBy target of 2 separate relationships.
EclipseLink appears to handle this perfectly well, and Hibernate should too.
Darren Kelly (Webel IT Australia)
was (Author: webel):
I would like to confirm that this feature also works in EclipseLink (and in OpenJPA as
observed above), and want to like others above make the case for support, instead of
rejection, of this feature.
cant bind a child using mappedby relating to a parent
attribute(polymorphism)
-----------------------------------------------------------------------------
Key: HHH-4233
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-4233
Project: Hibernate Core
Issue Type: Bug
Components: annotations
Environment: osx 10.4, java 1.5
Reporter: Nino Martinez
Assignee: Emmanuel Bernard
Attachments: JPA101.zip
This is pseudo class hieracy
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
Mammal
{
@ManyToOne
Person owner;
}
@Entity
Cat extends Mammal
Person{
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.REMOVE }, mappedBy = "owner")
private List<Cat> cats = new ArrayList<Cat>();
}
it gives the error mission property:
javax.persistence.PersistenceException: org.hibernate.AnnotationException: mappedBy
reference an unknown target entity property:
Cat.owner in Person.cats
This is the related thread on hibernate forum:
http://forum.hibernate.org/viewtopic.php?p=2380570#2380570
I can confirm that the same example does work when using OpenJPA as a provider. Please
see attached project for reference.
Please do not hesitate me if you have questions.
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira