[hibernate-issues] [Hibernate-JIRA] Issue Comment Edited: (HHH-4233) cant bind a child using mappedby relating to a parent attribute(polymorphism)

Darren Kelly (JIRA) noreply at atlassian.com
Mon Nov 28 04:04:20 EST 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-4233?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=44443#comment-44443 ] 

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

        


More information about the hibernate-issues mailing list