-->
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: Criteria projection bug with table per subclass mapping
PostPosted: Tue Apr 10, 2007 3:03 pm 
Newbie

Joined: Sun Mar 14, 2004 2:41 pm
Posts: 2
I believe I have found a bug when using projections via the criteria api in a table per subclass hierarchy.

I essentially have 4 different tables. Table A is the parent of Tables B, C, and D, e.g. table B, C, and D have a reference to the PK of Table A via a FK.

I have classes ClassA, ClassB, ClassC, and ClassD that map to the corresponding tables and B,C,D extend A.

So here is where the bug comes in. I actually have a field, let's call it "someField", that is common to both Class B and C, but not D. Therefore I can't put it in ClassA.

So in my ClassA.hbm.xml file I have mapped Class B, C, and D via <joined-subclass> tags and in the definitions of Class B and C I have a property defined called "someField".

<joined-subclass name="com.acme.ClassB"
<property name="someField" type="java.lang.String">
<column name="SOME_FIELD_B" length="35" />
</property>
</joined-subclass>
<joined-subclass name="com.acme.ClassC"
<property name="someField" type="java.lang.String">
<column name="SOME_FIELD_C" length="45" />
</property>
</joined-subclass>

That being said I should now be able to setup a criteria query using Projections to just select "someField" from both table B and C. e.g. :

Code:
getSession().createCriteria(ClassA.class)
                      .setProjection(Projections.projectionList()
            .add(Property.forName("someField"))
            .list();


The resulting sql is incorrectly generated as :

select this_1_.SOME_FIELD_C as y0_,
from TABLE_A this_,
TABLE_B this_1_,
TABLE_C this_2_,
where this_.SRC_REC_ID=this_1_.SRC_REC_ID(+)
and this_.SRC_REC_ID=this_2_.SRC_REC_ID(+)

This is wrong because TABLE_B does not contain SOME_FIELD_C!!! it contains SOME_FIELD_B!!

Now I would suspect that you are now saying "Why don't you just create a new class, ClassBC that contains the common field, someField". This may indeed be the way to go, but there should at least be an error message at startup that indicates that you can't map a field with the same name in a hierarchy.

My question to the hibernate developers is : "Why couldn't you have two fields with the same name in 2 different classes in a hierarchy?". The generated sql could just map to both mapped properties in the appropriate classes.

I'd like to get some feedback on this to see what others think before I post it to JIRA.

Thanks,
Dave

FYI : I'm using Hibernate version: 3.2.3 GA[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 10, 2007 5:01 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Not a bug. If someField isn't a property of class A, then you can't search for all As that have a particular value for it. You'll need two critera, one each for classes B and C.

BTW, you don't make classes B, C and D extend class A just because they have some properties in common, as you imply in your post. If B, C and D don't have an is-a relationship with A, then they should not extend it. Delegation is more appropriate. And if you use delegation (mapped in hibernate as one-to-one or many-to-one relationships, as appropriate) then you can create a single criteria to find all Bs and Cs that have someField = X.

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


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 11, 2007 9:52 am 
Newbie

Joined: Sun Mar 14, 2004 2:41 pm
Posts: 2
tenwit wrote:
Not a bug. If someField isn't a property of class A, then you can't search for all As that have a particular value for it. You'll need two critera, one each for classes B and C.


I don't agree with you. The criteria api is generating an incorrect query that results in a database error. That has to warrant some attention, no matter the implementation.

I also think its pretty ugly to have to create two criteria queries, one for each class. Shouldn't the criteria api be smart enough to know what subclasses are mapped to the parent class?

Why can't it just generate a query that selects both fields from TableB and TableC based on both fields from ClassB and ClassC? This wouldn't be that hard to do.

tenwit wrote:
BTW, you don't make classes B, C and D extend class A just because they have some properties in common, as you imply in your post. If B, C and D don't have an is-a relationship with A, then they should not extend it. Delegation is more appropriate. And if you use delegation (mapped in hibernate as one-to-one or many-to-one relationships, as appropriate) then you can create a single criteria to find all Bs and Cs that have someField = X.


In response, B, C, and D's relationship with A is an "is-a" relationship. It just so happens that B and C have an identical field name.

Now, if the requirement for hibernate is that you can't use any duplicate field names in sub class mappings then there should be an error on startup!! or at least something to indicate that there are potential issues with the mapping.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 11, 2007 5:22 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
puppetmasta wrote:
Shouldn't the criteria api be smart enough to know what subclasses are mapped to the parent class?

They could be, but that wouldn't be very polymorphic. Object orientation requires that classes know about their superclasses, not the other way around.

puppetmasta wrote:
Now, if the requirement for hibernate is that you can't use any duplicate field names in sub class mappings

That's not a requirement. The requirement is that polymorphism is used correctly. You can search in A and all subclasses for any field in A, but you can't search in A for any field that isn't in A. It works like this in java, C++. and presumably every other implementation of polymorphism: it's just the rule. If hibernate did it differently, it would have to make it clear that the feature is not due to polymorphism, it's some special, hibernate-specific feature.

Either way, it's most definitely not a bug. It's a feature that you'd like to see implemented.

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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 21, 2007 12:04 pm 
Newbie

Joined: Tue Mar 21, 2006 9:25 am
Posts: 8
tenwit wrote:
puppetmasta wrote:
Shouldn't the criteria api be smart enough to know what subclasses are mapped to the parent class?

They could be, but that wouldn't be very polymorphic. Object orientation requires that classes know about their superclasses, not the other way around.


Agreed but given that an empty Criteria contains all the necessary associations and aliases it would be a great feature to be able to use Projections on fields of the subclasses. In this case it's not really an issue of polymorphism, you're simply requesting a subset of the columns from the query result.

Applying Restrictions on the subclass fields would be a different issue as this is a much clearer violation of polymorphism.


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.