-->
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.  [ 6 posts ] 
Author Message
 Post subject: Entities, inheritance and cast problems
PostPosted: Tue Mar 31, 2009 6:16 am 
Beginner
Beginner

Joined: Mon Jan 10, 2005 7:14 am
Posts: 32
Hi,

I use JPA / Hibernate (3.2.6.GA) and I encounter a problem using inheritance and entities.

I have 4 entities :
- Population
- PopulationCriterion, abstract one
- SimpleExpression, that extends PopulationCriterion
- LogicalExpression, that extends PopulationCriterion

Population entity has a "rootCriterion" property, that points to a population criterion that can be either a simple expression instance, either a logical expression instance.

Here is a picture of the model :

Image

I run the following unit test :

Code:
Population population = dao.findByCode("POP_1");
assert population.getId() != null;
assert "POP_1".equals(population.getCode());
assert population.getRootCriterion() != null;
assert population.getRootCriterion() instanceof SimpleExpression;
SimpleExpression rootCriterion = (SimpleExpression) population.getRootCriterion();


But it fails on "instanceof". Using getClass().getName() I can see that rootCriterion property is of PopulationCriterion type, while it is an abstract class ! I expected it to be either SimpleExpression, either LogicalExpression, but not PopulationCriterion !

I understood that Hibernate supported inheritance, so I can't understand why it has problem with this. Or maybe there is something that I misunderstood ?

Here are some interesting extracts (I think !) of my entities :

Population.java :

Code:
@Entity
public class Population
{
    ... 
    private PopulationCriterion rootCriterion;

    @ManyToOne(optional = false, cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinColumn(name = "ROOT_CRITERION_FK_")
    public PopulationCriterion getRootCriterion()
    {
        return this.rootCriterion;
    }
    ...
}


PopulationCriterion.java :

Code:
@Entity
public abstract class PopulationCriterion
{
    ...
}


SimpleExpression.java :

Code:
@Entity
public class SimpleExpression
    extends PopulationCriterion
{
    ...
}


LogicalExpression.java :

Code:
@Entity
public class LogicalExpression
    extends PopulationCriterion
{
    ...
}


I desperately try to understand what happens since yesterday, so any help is very welcome ;)

Thanks in advance

Olivier


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 31, 2009 6:20 am 
Beginner
Beginner

Joined: Mon Jan 10, 2005 7:14 am
Posts: 32
Sorry, I forgot to paste part of entities configuration (done in orm.xml file) :

Code:
<entity class="Population">
      <table name="HQPOP_POPULATION">
      </table>
       <named-query name="Population.findAll">
          <query><![CDATA[select population from Population AS population]]></query>
       </named-query>
        <named-query name="Population.findByCode">
           <query><![CDATA[from Population as population where population.code = :code]]></query>
        </named-query>
</entity>
<entity class="PopulationCriterion">
      <table name="HQPOP_POPULATION_CRITERION">
      </table>
        <inheritance strategy="JOINED" />
       <named-query name="PopulationCriterion.findAll">
          <query><![CDATA[select populationCriterion from PopulationCriterion AS populationCriterion]]></query>
       </named-query>
</entity>
<entity class="LogicalExpression">
      <table name="HQPOP_LOGICAL_EXPRESSION">
      </table>
       <named-query name="LogicalExpression.findAll">
          <query><![CDATA[select logicalExpression from LogicalExpression AS logicalExpression]]></query>
       </named-query>
</entity>
<entity class="SimpleExpression">
      <table name="HQPOP_SIMPLE_EXPRESSION">
      </table>
       <named-query name="SimpleExpression.findAll">
          <query><![CDATA[select simpleExpression from SimpleExpression AS simpleExpression]]></query>
       </named-query>
</entity>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 31, 2009 7:50 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
It seems like the issue that is discussed in the Hibernate documentation: http://www.hibernate.org/hib_docs/v3/re ... ng-proxies


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 31, 2009 8:50 am 
Beginner
Beginner

Joined: Mon Jan 10, 2005 7:14 am
Posts: 32
Thanks a lot, I think you helped me to understand what happens.

Just before reading your post, I had noted that I had no more problem when using EAGER fetch type instead of LAZY one. And your link gives some explanation about that. If I understood well, I should not use lazy loading on single-ended association if the association end is a polymorphic class ? Do you know if this issue will be solved in the future ?

Anyway I need to set this association as a lazy one for performance problems. So I will transform it to a many to many association, lazy loading should work with this one. And I will check that the underlying collection has only one element. Not perfect, but it should work I think !

Regards,

Olivier


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 31, 2009 1:37 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
The problem is that Hibernate can't know the proper subclass without loading the entity. So, the "fix" is to not use proxies. And this means that you either have to use eager loading (lazy="false") or lazy="no-proxy". The latter option requires byte-code manipulation of the compiled classes to make Hibernate intercept the call to the getter method (see http://www.hibernate.org/hib_docs/v3/re ... properties). I have no experience with this method, but it seems like a good candidate for your case.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 01, 2009 3:50 am 
Beginner
Beginner

Joined: Mon Jan 10, 2005 7:14 am
Posts: 32
Well, it looks too complicated for me. The most important for me is using lazy loading, so I will use a many association instead of single-ended one. It's not really a problem for me and I know it works well ;) 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.  [ 6 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.