-->
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.  [ 7 posts ] 
Author Message
 Post subject: one-to-one relationship with same comp primary key
PostPosted: Fri Oct 28, 2005 5:17 am 
Newbie

Joined: Tue Oct 05, 2004 4:33 pm
Posts: 4
Location: Trondheim, Norway
I've got two tables, TableParent and TableChild:
Code:
+---------------+             +----------------+
| TableParent   |             | TableChild     |
+---------------+             +----------------+
| Composed   PK |-------------| Composed PK/FK |
| Key        PK |             | Key      PK/FK |
| Attribute     |             | ChildAttribute |
+---------------+             +----------------+


As you can see, TableChild's primary key is the foreign key from TableParent.

I guess I should have made a mapping file describing this as TableChild extending TableParent, but I didn't, in stead I defined this as a one-to-one mapping:

TableParent.hbm.xml:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > 
<hibernate-mapping>
<class
    name="error.demo.hibernate.composite_keys.model.TableParent"
    table='"TableParent"'
>
    <meta attribute="implement-equals" inherit="false">true</meta>
    <composite-id name="comp_id" class="error.demo.hibernate.composite_keys.model.TableParentPK">
        <key-property
            name="composed"
            column="Composed"
            type="long"
            length="10"
        />
        <key-property
            name="key"
            column="Key"
            type="long"
            length="10"
        />
    </composite-id>   
    <property
        name="attribute"
        type="java.lang.Long"
        column="Attribute"
        length="10"
    />
    <one-to-one
        name="tableChild"
        class="error.demo.hibernate.composite_keys.model.TableChild"
        outer-join="auto"
    />

</class>
</hibernate-mapping>


TableChild.hbm.xml:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class
    name="error.demo.hibernate.composite_keys.model.TableChild"
    table='"TableChild"'
>
    <meta attribute="implement-equals" inherit="false">true</meta>
    <composite-id name="comp_id" class="error.demo.hibernate.composite_keys.model.TableChildPK">
        <key-property
            name="composed"
            column="Composed"
            type="long"
            length="10"
        />
        <key-property
            name="key"
            column="Key"
            type="long"
            length="10"
        />
    </composite-id>   
    <property
        name="childAttribute"
        type="java.lang.String"
        column="ChildAttribute"
        length="19"
    />
    <one-to-one
        name="tableParent"
        class="error.demo.hibernate.composite_keys.model.TableParent"
        outer-join="auto"
        constrained="true"
    />
</class>
</hibernate-mapping>


So far so good, no complaints when configuring hibernate. But if I manually insert a row in TableParent and TableChild, and ask hibernate to load this row, using
Code:
         TableParentPK pk = new TableParentPK(1,2);
         TableParent pi = (TableParent) s.load(TableParent.class, pk);


I get an ugly ClassCastException, deep down in CGLIB:
Code:
Exception in thread "main" java.lang.RuntimeException: net.sf.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of error.demo.hibernate.composite_keys.model.TableParentPK.?
   at error.demo.hibernate.composite_keys.CompositeKeyErrorDemo.main(CompositeKeyErrorDemo.java:41)
Caused by: net.sf.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of error.demo.hibernate.composite_keys.model.TableParentPK.?
   at net.sf.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:193)
   at net.sf.hibernate.type.ComponentType.nullSafeGetValues(ComponentType.java:164)
   at net.sf.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:151)
   at net.sf.hibernate.loader.Loader.bindPositionalParameters(Loader.java:753)
   at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:793)
   at net.sf.hibernate.loader.Loader.doQuery(Loader.java:269)
   at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:138)
   at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:941)
   at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:961)
   at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:59)
   at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:51)
   at net.sf.hibernate.persister.EntityPersister.load(EntityPersister.java:413)
   at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2131)
   at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:2001)
   at net.sf.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1963)
   at net.sf.hibernate.type.OneToOneType.resolveIdentifier(OneToOneType.java:71)
   at net.sf.hibernate.type.EntityType.resolveIdentifier(EntityType.java:208)
   at net.sf.hibernate.impl.SessionImpl.initializeEntity(SessionImpl.java:2219)
   at net.sf.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:319)
   at net.sf.hibernate.loader.Loader.doQuery(Loader.java:309)
   at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:138)
   at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:941)
   at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:961)
   at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:59)
   at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:51)
   at net.sf.hibernate.persister.EntityPersister.load(EntityPersister.java:413)
   at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2131)
   at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:2001)
   at net.sf.hibernate.impl.SessionImpl.load(SessionImpl.java:1930)
   at error.demo.hibernate.composite_keys.CompositeKeyErrorDemo.main(CompositeKeyErrorDemo.java:39)
Caused by: java.lang.ClassCastException
   at error.demo.hibernate.composite_keys.model.TableParentPK$$BulkBeanByCGLIB$$6222dd4a.getPropertyValues(<generated>)
   at net.sf.cglib.beans.BulkBean.getPropertyValues(BulkBean.java:86)
   at net.sf.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:190)
   ... 29 more


If I replace the TableChildPK with a TableParentPK, then it works, but shouldn't this work as well? (the mapping files were originally generated by middlegen, that's why the PK classes are two separate classes in the first place)


Hibernate version: 2.1.8


Eivind


Top
 Profile  
 
 Post subject: the same PK
PostPosted: Fri Oct 28, 2005 10:52 am 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
According to
http://www.hibernate.org/hib_docs/v3/re ... n-onetoone
the classes should have the same PK, or have many-to-one mapping even it is one-2-one business wise

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 28, 2005 6:15 pm 
Newbie

Joined: Tue Oct 05, 2004 4:33 pm
Posts: 4
Location: Trondheim, Norway
Sorry for being dense, I'd just like to make sure I really understand this. The docs say:
Quote:
Primary key associations don't need an extra table column; if two rows are related by the association then the two table rows share the same primary key value. So if you want two objects to be related by a primary key association, you must make sure that they are assigned the same identifier value!


As seen from the database, these two rows do share the same primary key value. So I guess the above text refers to the Java primary key, i.e. the PK must be the same value and PK-class, right?

That also explains why this isn't a problem for a relation between two classes without composite PKs, since these automatically shares the same primary key class.



Eivind


Top
 Profile  
 
 Post subject: yes
PostPosted: Fri Oct 28, 2005 6:18 pm 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
correct

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


Top
 Profile  
 
 Post subject: Still getting the same error
PostPosted: Fri Nov 04, 2005 9:48 am 
Newbie

Joined: Tue Oct 05, 2004 4:33 pm
Posts: 4
Location: Trondheim, Norway
I've changed my mapping files according to your advice. TableParent.hbm.xml is unchanged, while TableChild.hbm.xml now looks like:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
   
<hibernate-mapping>

<class
    name="error.demo.hibernate.composite_keys.model.TableChild"
    table='"TableChild"'
>
    <meta attribute="implement-equals" inherit="false">true</meta>

    <composite-id name="comp_id" class="error.demo.hibernate.composite_keys.model.TableChildPK">
        <key-property
            name="composed"
            column="Composed"
            type="long"
            length="10"
        />
        <key-property
            name="key"
            column="Key"
            type="long"
            length="10"
        />
    </composite-id>   

    <property
        name="childAttribute"
        type="java.lang.String"
        column="ChildAttribute"
        length="19"
    />

     <many-to-one
        name="tableParent"
        class="error.demo.hibernate.composite_keys.model.TableParent"
        unique="true"
      insert="false"
      update="false"
    >
        <column name="composed" />
        <column name="key" />
    </many-to-one>

</class>
</hibernate-mapping>


Unfortunately, I'm still getting the same error:
    Hibernate: select tableparen0_.Composed as Composed1_, tableparen0_.Key as Key1_, tableparen0_.Attribute as Attribute1_, tablechild1_.Composed as Composed0_, tablechild1_.Key as Key0_, tablechild1_.ChildAttribute as ChildAtt3_0_, tablechild1_.composed as composed0_, tablechild1_.key as key0_ from "TableParent" tableparen0_ left outer join "TableChild" tablechild1_ on tableparen0_.Composed=tablechild1_.Composed and tableparen0_.Key=tablechild1_.Key where tableparen0_.Composed=? and tableparen0_.Key=?
    Hibernate: select tablechild0_.Composed as Composed1_, tablechild0_.Key as Key1_, tablechild0_.ChildAttribute as ChildAtt3_1_, tablechild0_.composed as composed1_, tablechild0_.key as key1_, tableparen1_.Composed as Composed0_, tableparen1_.Key as Key0_, tableparen1_.Attribute as Attribute0_ from "TableChild" tablechild0_ left outer join "TableParent" tableparen1_ on tablechild0_.composed=tableparen1_.Composed and tablechild0_.key=tableparen1_.Key where tablechild0_.Composed=? and tablechild0_.Key=?
    Exception in thread "main" java.lang.RuntimeException: net.sf.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of error.demo.hibernate.composite_keys.model.TableChildPK.?
    at error.demo.hibernate.composite_keys.CompositeKeyErrorDemo.main(CompositeKeyErrorDemo.java:42)
    Caused by: net.sf.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of error.demo.hibernate.composite_keys.model.TableChildPK.?
    at net.sf.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:193)
    at net.sf.hibernate.type.ComponentType.nullSafeGetValues(ComponentType.java:164)
    at net.sf.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:151)
    at net.sf.hibernate.loader.Loader.bindPositionalParameters(Loader.java:753)
    at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:793)
    at net.sf.hibernate.loader.Loader.doQuery(Loader.java:269)
    at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:138)
    at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:941)
    at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:961)
    at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:59)
    at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:51)
    at net.sf.hibernate.persister.EntityPersister.load(EntityPersister.java:413)
    at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2131)
    at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:2001)
    at net.sf.hibernate.impl.SessionImpl.internalLoadOneToOne(SessionImpl.java:1955)
    at net.sf.hibernate.type.OneToOneType.resolveIdentifier(OneToOneType.java:71)
    at net.sf.hibernate.type.EntityType.resolveIdentifier(EntityType.java:208)
    at net.sf.hibernate.impl.SessionImpl.initializeEntity(SessionImpl.java:2219)
    at net.sf.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:319)
    at net.sf.hibernate.loader.Loader.doQuery(Loader.java:309)
    at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:138)
    at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:941)
    at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:961)
    at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:59)
    at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:51)
    at net.sf.hibernate.persister.EntityPersister.load(EntityPersister.java:413)
    at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2131)
    at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:2001)
    at net.sf.hibernate.impl.SessionImpl.load(SessionImpl.java:1930)
    at error.demo.hibernate.composite_keys.CompositeKeyErrorDemo.main(CompositeKeyErrorDemo.java:39)
    Caused by: java.lang.ClassCastException
    at error.demo.hibernate.composite_keys.model.TableChildPK$$BulkBeanByCGLIB$$f2559bc.getPropertyValues(<generated>)
    at net.sf.cglib.beans.BulkBean.getPropertyValues(BulkBean.java:86)
    at net.sf.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:190)
    ... 29 more


Am I still doing something wrong?

I have a complete simple test program if that's useful.


Eivind


Top
 Profile  
 
 Post subject: yes, test is useful
PostPosted: Fri Nov 04, 2005 11:28 am 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
send it to me please.

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


Top
 Profile  
 
 Post subject: PK
PostPosted: Fri Nov 04, 2005 6:40 pm 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
TableChild should use TableParentPK as PK

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


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