-->
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.  [ 4 posts ] 
Author Message
 Post subject: How to query for unreferenced objects?
PostPosted: Thu Apr 22, 2004 8:09 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
There are several ways to phrase this question, and I think I know the answer, but here goes anyway.

I have a two-way many-to-many mapping:
Code:
<hibernate-mapping>

    <class name="com.nimblefish.core.domain.asset.Asset">
        <id name="id" type="long" unsaved-value="null" >
            <generator class="native"/>
        </id>

        <property name="name" type="string"/>

        <!-- assets have multiple versions (and versions can be in multiple assets) -->
        <list name="versions" table="asset_to_version" lazy="true" cascade="all-delete-orphan">
            <key column="asset_id"/>
            <index column="asset_index"/>
            <many-to-many column="version_id" class="com.nimblefish.core.domain.asset.Version"/>
        </list>
    </class>

    <!-- A Version is an immutable pointer to a particular item in the version store, or else
         an immutable pointer to multiple child Versions.  Versions are transitively immutable
         once constructed. -->
    <class name="com.nimblefish.core.domain.asset.Version">

        <id name="id" type="long" unsaved-value="null" >
            <generator class="native"/>
        </id>

        <property name="name" type="string"/>

        <!-- assets have a version history, but versions are NOT a strict parent-child relationship since
             a single version can be in the version history of multiple assets. -->
        <set name="assets" table="asset_to_version" lazy="true" inverse="true">
            <key column="version_id"/>
            <many-to-many column="asset_id" class="com.nimblefish.core.domain.asset.Asset"/>
        </set>

    </class>

</hibernate-mapping>

Like I said, a two-way many-to-many.

Now. Let's say we have the following contents of our tables:
Code:
Asset
asset_id  name
1         "foo"
2         "bar"

Version
version_id   name
1            "foo"
2            "bar"

asset_to_version
asset_id   version_id
1          1
1          2
2          1

What I want is to be able to clean up unreferenced Versions when there are no existing Assets that reference them. So let's say I delete asset 1, which cleans up the references from asset 1 to versions 1 and 2. Now version 2 is unreferenced by any Asset.

I want to write an HQL query which selects for all (and only) the Versions that are unreferenced by an Asset.

Some wild stabs in the dark at how this might look:
Code:
from Version v where count(v.assets) = 0

But this doesn't work because you can't use collections in a where clause, let alone collection functions. When trying it in hibern8ide, I get
Code:
net.sf.hibernate.QueryException: unindexed collection before []: version0_.assets


In SQL, one could write:
Code:
select * from Version where not exists (select * from asset_to_version where asset_to_version.version_id = version.version_id)

But Hibernate doesn't support subselects.

Or:
Code:
select * from Version left outer join asset_to_version on version.version_id = asset_to_version.version_id where asset_to_version.version_id = null

But Hibernate doesn't support arbitrary outer joins (according to http://forum.hibernate.org/viewtopic.php?p=2199096#2199096 anyway).

So. Can anyone suggest any crafty way to do this in HQL? Or am I down in the world of pass-through SQL? (And can you experiment with pass-through SQL in Hibern8IDE?)

Cheers!
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 22, 2004 8:19 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
http://www.hibernate.org/hib_docs/reference/html/query-language.html#query-language-s9


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 22, 2004 8:25 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Ya, I feel dumb. Just read up on that after posting.

Why doesn't this work?
Code:
from Version version where not exists elements(version.assets)


And for bonus points, can anyone suggest an HQL way of doing this in databases that DON'T support subselects? (We run MySQL on our development machines....)

Cheers!
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 22, 2004 8:33 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Never mind. The query above ("where not exists elements(version.assets)") DOES work. And is really lovely to boot.

Sorry for not reading the documentation!!!!!!!!!!!!!!! :-( :-( :-(

Cheers
Rob


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.