-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Help Polymorphic queries, One-to-Many, and owners?
PostPosted: Mon Jun 26, 2006 11:58 am 
Beginner
Beginner

Joined: Tue Nov 29, 2005 4:42 pm
Posts: 49
Location: Atlanta, GA
I'm really having trouble creating some queries for my domain model. I need some guidance.

I have two classes Component, and Group that contain DocumentInstances through a OneToMany relationship. I'm using two join tables to map that relationship.

Here is the mapping for Group and Component:

Code:
public class Component {

    @OneToMany(fetch = FetchType.LAZY, targetEntity = DocumentInstance.class )
    @JoinTable(
            name="DocumentInstances_Components",
            joinColumns = { @JoinColumn( name="ComponentID") },
            inverseJoinColumns = @JoinColumn( name="DocumentInstanceID")
    )
    private Set<DocumentInstance> documentInstances;

}

public class Group {

    @OneToMany(fetch = FetchType.LAZY, targetEntity = DocumentInstance.class )
    @JoinTable(
            name="DocumentInstances_Groups",
            joinColumns = { @JoinColumn( name="GroupID") },
            inverseJoinColumns = @JoinColumn( name="DocumentInstanceID")
    )
    private Set<DocumentInstance> documentInstances;

}


Now I have DocumentInstance and it contains two associations to SchemaNamespace through a ManyToOne and BinaryData through a OneToOne relationship. Here is his mapping:

Code:
public class DocumentInstance {

    @ManyToOne( fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn( name = "NamespaceID", nullable =  false )
    private SchemaNamespace namespace;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn( name = "BinaryDataID" )
    private BinaryData binaryData;
}


Now I'm trying to fetch the associated BinaryData object given a Group and SchemaNamespace object, and given a Component and SchemaNamespace object (i.e. two different queries). This seems like it's a polymorphic query, but I don't know how to specify the id for a group vs. a component. I read in the Manning book that this type of query isn't supported by Hibernate, but I could map it using the <any> element. I have no idea what this might be in annotations. This is where I begin to think that I might need to seperate tables to map this because of the query I'm trying to run. One for DocumentInstances belonging to Components and one for DocumentInstances belonging to Groups. If I did this how would I create two mappings for one object with annotations? Then what's worse using <any> elements or mapping an object twice?

Should I create an Interface for Group and Component to implement and map an owner property in DocumentInstance. If I do that how will Hibernate know I want the DocumentInstance with this namespace and owned by this Group vs. I want the DocumentInstance with this namespace and owned by this Component?

I tried a query like:
Code:
        from Group as g join g.documentInstances as di where
            g.id = :id
            and di.namespace.namespace = :namespace


But that loaded a full group object with all of it's DocumentInstances fully loaded, and it gave me a DocumentInstance in a Object[] array. Seems like I need to do something like:

Quote:
from DocumentInstance di join Group g where g.id = :id and di.namespace.namespace = :namespace


This would seem like a quite common problem.

Utterly confused.
Charlie


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 27, 2006 10:33 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
There's no polymorphism here: no super/subclass relationship. You cannot write a query like "select (g from Group g or c from Component c) ...". You need two separate queries. You can make it polymorphic using your interface idea, and use the tabe-per-concrete-class strategy: see section 5.1.17 of the ref docs.

To have only the Group objects returned from your query, use "select g from Group g ..." and the rest of your query.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 28, 2006 9:19 am 
Beginner
Beginner

Joined: Tue Nov 29, 2005 4:42 pm
Posts: 49
Location: Atlanta, GA
It I added an interface and created a polymorphic query what would the query look like?

select di from DocumentInstance di where owner = ?

What would the owner be? And how will Hibernate know which table to join against? Say I pass in a Group as the owner. Then say I pass in a Component as the owner. What if I did this:

select di from DocumentInstance di where owner.id =?

Then there is no typing information. How will hibernate figure it out?

Charlie


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 28, 2006 5:16 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
The ref docs explain polymorphic mappings well. Its all in section 9. For your setup, you'll need table per concrete class, sections 5.1.17 and 9.1.5. Your DocumentInstance mapping will contain a many-to-one to the common interface. You common interface will be mapped as described in section 9.1.5: no table, but two union-subclasses, Component and Group, which do have tables. If the common interface is called Owner, you can then write your query as
Code:
from DocumentInstance di where di.Owner = ?
Hibernate will generate a query something like
Code:
select (document instance fields) from DocuemntInterface where ownerid = ?
If you were doing a query on some field inside the Owner interface (ids are the simple case), the query would be a union:
Code:
select (document instance fields) from DocuemntInterface di
join Group g on di.ownerid = g.groupid
where g.SomeField = ?
union
select (document instance fields) from DocuemntInterface di
join Component c on di.ownerid = c.componentid
where c.SomeField = ?

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 30, 2006 11:01 am 
Beginner
Beginner

Joined: Tue Nov 29, 2005 4:42 pm
Posts: 49
Location: Atlanta, GA
Thank you tenwit. I don't know how many times I've read those sections and I didn't see those. I know all the documentation is there it's just hard to find what pertains to my situation and what doesn't. Thanks for your help.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.