Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Specify subclass on joined inheritance.
PostPosted: Thu Jul 27, 2017 12:00 pm 
Newbie

Joined: Thu Jul 27, 2017 11:51 am
Posts: 6
Hello! I'm hoping someone can help me out with a problem I'm having using a table per subclass inheritance model in hibernate 4.3.11.

I have a class that links the inheritance class...

Code:
@Entity
@Table(name = "ASSOC")
public class Assoc {
    @ManyToOne(fetch = FetchType.LAZY)
    private Obj from;

    @ManyToOne(fetch = FetchType.LAZY)
    private Obj to;
}


And the inheritance classes look like this...

Code:
@Entity
@Table(name = "OBJECT")
@Inheritance(strategy= InheritanceType.JOINED)
@DiscriminatorColumn(name = "CODE")
public class Obj {
   // .... stuff
}


@Entity
@Table(name = "OBJECT_A")
@PrimaryKeyJoinColumn(name="ID")
@DiscriminatorValue("A")
public class ObjA extends Obj {
   // .... A stuff
}

@Entity
@Table(name = "OBJECT_B")
@PrimaryKeyJoinColumn(name="ID")
@DiscriminatorValue("B")
public class ObjB extends Obj {
   // .... B stuff
}


This models what I need perfectly, one main table that contains common properties and sub tables that contain specific properties. The problem is that I want to query Assocs based on specific subclasses something like...

Code:
session.createCriteria(Assoc.class)
    .add(Restrictions.eq("from", fromObj))
    .add(Restrictions.eq("to.class", ObjB.class)


However, I'm getting LEFT JOINs for each subclass and a CASE WHEN THEN statement at the end to filter the subclass.

I find it a little hard to believe that there isn't some mechanism in Hibernate that would let me tell the query the specific subclass that I'm looking for and avoid the greedy joins.

Any help would be appreciated.


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Thu Jul 27, 2017 12:11 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1433
Try with:

Code:
select a
from Assoc a
where
    a.from = :fromObj
    and TYPE(a.to) = :subtype

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Thu Jul 27, 2017 12:14 pm 
Newbie

Joined: Thu Jul 27, 2017 11:51 am
Posts: 6
vlad wrote:
Try with:

Code:
select a
from Assoc a
where
    a.from = :fromObj
    and TYPE(a.to) = :subtype



Is there a way to do this with Restrictions on a Criteria instead of HQL?


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Thu Jul 27, 2017 3:33 pm 
Newbie

Joined: Thu Jul 27, 2017 11:51 am
Posts: 6
Also when I try this I get a QueryException stating

Could not resolve property: class of: ...Assoc

If I take off the
Code:
type(assoc.to) = :toClass
part I don't get the error


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Thu Jul 27, 2017 3:39 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1433
Quote:
Is there a way to do this with Restrictions on a Criteria instead of HQL?


Hibernate Legacy Criteria is deprecated and we'll be removed in a future version of Hibernate.

As for the exception, try it like this:

Code:
select a
from Assoc a
JOIN TREAT(a.to AS ObjB) b
where
    a.from = :fromObj

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Fri Jul 28, 2017 12:19 pm 
Newbie

Joined: Thu Jul 27, 2017 11:51 am
Posts: 6
Thanks for the help Vlad, you got me way closer than I was before, but I'm still running into an issue.

So when I do my hql as follows

Code:
select assoc
from Assoc
join treat(assoc.to as ObjB)
where assoc.from = :fromEntity


It actually works nicely and I get sql that looks like this...

Code:
select
    assoc.properties
from
    ASSOC assoc
inner join
    OBJ obj
        on assoc.to_id = obj.id
inner join
    OBJB objb
        on obj.id = objb.id
where
    assoc.from_id=?


Then when the code tries to retrieve a property for objb it runs into joins again.

To try and mitigate this I tried to get objb more eagerly by including it in my query like...

Code:
select assoc, assoc.to
from Assoc
join treat(assoc.to as ObjB) b
where assoc.from = :fromEntity

(note: I also tried using the alias in the select)

This for some reason puts all of the joins back in.

The exceptionally strange part is that it left outer joins all the objects, except objb which it keeps as an inner join.

Do you have any other suggestions, at this point I'm about ready to pick through the library code to see if this might be a bug somehow.

Thanks again for all your help so far!


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Fri Jul 28, 2017 2:19 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1433
What if you try with:

Code:
select assoc
from Assoc
join fetch treat(assoc.to as ObjB)
where assoc.from = :fromEntity

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Fri Jul 28, 2017 2:28 pm 
Newbie

Joined: Thu Jul 27, 2017 11:51 am
Posts: 6
Seems to get the same joins as including the to obj in the select. I think I'm going to try to use a single table inheritance with secondary tables for my additional properties, not ideal, but others with this same issue have found this to work better.


Top
 Profile  
 
 Post subject: Re: Specify subclass on joined inheritance.
PostPosted: Tue Aug 01, 2017 12:09 pm 
Newbie

Joined: Thu Jul 27, 2017 11:51 am
Posts: 6
Found a good solution so I figured I would post it here in case someone else runs into a similar issue.

First I attempted to go to a single table inheritance and ran into similar problems. I think the real crux of the problem was that I was using the JPA @Table annotation. I found that switching to @org.hibernate.annotations.Table and using the FetchMode.SELECT parameter worked wonders. I left it as single table inheritance so I'm not sure if this would have fixed the joined inheritance problems and unfortunately I don't have time to fuss with it further.

Thanks again for your suggestions, Vlad! I really appreciate you taking the time to work with me on this!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 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.