-->
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.  [ 8 posts ] 
Author Message
 Post subject: Getting NULL in fields of join table of collection
PostPosted: Mon Aug 16, 2004 3:39 pm 
Newbie

Joined: Fri Jul 02, 2004 9:05 pm
Posts: 10
Ok, here's what I'm seeing, as simple as I can:

I have a ProfileObject.class which is linked by primary key "id" to a ProfileQuestion.class having primary key "qid" via an intermediate class ProfileProperty.class (Fields "pid" and "qid"). The three classes persist correctly to a Profiles table, Profile_Properties table and Profile_Questions table (mapping documents below).

The relationship is represented by a "Set" in the ProfileObject.class.

I can create a new profile in the Profiles table, and then add properties (objects to the Set) which cause an id and qid to be written correctly to the ProfileProperties table (the ProfileQuestions table already exists). When I perform a "get" of a profile, a ProfileProperty object looks like this:

"NULL NULL questionid questiontype questiontext"

The two nulls are supposed to be id and qid from the ProfileProperties object, which do indeed exist. The next three fields are correctly obtained from the Profile_Questions table.

The nulls are causing havoc when I use "contains" on the Set, even though I take it into account in my "Hashcode" implementation.

I suspect a mapping issue, so here are the mapping documents:


Code:
    <!-- ProfileObject.hbm.xml -->
    <class
        name="gov.alaska.ezdoc.ProfileObject"
        table="profiles"
        dynamic-update="false"
        dynamic-insert="false">

        <id
            name="id"
            column="id"
            type="java.lang.String">
            <generator class="assigned">
            </generator>
        </id>

        <set name="propertyList" table="profile_properties" lazy="false">
          <key column="pid"/>
         <composite-element class="gov.alaska.ezdoc.ProfileProperty">
            <many-to-one name="profileQuestion" class="gov.alaska.ezdoc.ProfileQuestion" column="qid"/>
         </composite-element>
        </set>
    </class>

    <!-- ProfileProperty.hbm.xml -->
    <class
        name="gov.alaska.ezdoc.ProfileProperty"
        table="profile_properties"
        dynamic-update="false"
        dynamic-insert="false">

      <!-- the qid field is a foreign key to the Profile_Questions table -->
        <id
            name="qid"
            column="qid"
            type="java.lang.String">
            <generator class="assigned">
            </generator>
        </id>

      <!-- the pid field is a foreign key to the Profiles table id field -->
        <property
            name="pid"
            type="java.lang.String"
            update="true"
            insert="true"
            column="pid"/>
    </class>

    <!-- ProfileQuestion.hbm.xml -->
    <class
        name="gov.alaska.ezdoc.ProfileQuestion"
        table="profile_questions"
        dynamic-update="false"
        dynamic-insert="false">

        <id
            name="qid"
            column="qid"
            type="java.lang.String">
            <generator class="assigned">
            </generator>
        </id>

        <property
            name="type"
            type="java.lang.String"
            update="true"
            insert="true"
            column="type"/>

        <property
            name="question"
            type="java.lang.String"
            update="true"
            insert="true"
            column="question"/>
    </class>



Ideas?

--Paul


Top
 Profile  
 
 Post subject: Re: Getting NULL in fields of join table of collection
PostPosted: Tue Aug 17, 2004 7:31 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
wizwoz wrote:
Ideas?

Paul, your composite element has primary key.

1). Try to replace your "propertyList" set by idbag, (read this 6.7. Using an <idbag>)
OR
2). don't use composite-element, and instead of it use many-to-many mapping (6.3. Collections of Values and Many-To-Many Associations).

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 7:38 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
In addition, you are using "assigned" generator in all your mappings, so should everywhere assign IDs manually, check it too.

_________________
Leonid Shlyapnikov


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 1:50 pm 
Newbie

Joined: Fri Jul 02, 2004 9:05 pm
Posts: 10
I think that my composite-element should NOT not have a primary key, because the link table, PROFILE_PROPERTIES consists only of two foreign keys, and it doesn't make much sense to create a primary key.

If I eliminate the compositie-element, I'm not sure what kind of object will be stored in the profileList collection, or how to map it.

FYI, I use a GUID generator in the constructors of ProfileObject.class and ProfileQuestion.class to create unique key strings, and can see them in the database.

--Paul


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 5:08 pm 
Newbie

Joined: Fri Jul 02, 2004 9:05 pm
Posts: 10
I have confirmed that at the time of a query or get, hibernate calls the null constructor for the profileProperty class for each item in the set, then calls the setProfiileQuestion method to populate it with an object representing the target row. The setPid and setQid methods never get called, so are defaulted to null (or whatever I set in the class).

So the question is, how to tell hibernate to call those setters at the same time during the query.

Alternatively, how to map the collection to persist the link table, but not with a class as I have done. This would result in having the set be a collection of ProfileQuestion objects, but as far as I could tell I could not persist a table without having a class and mapping file for it.

Understanding this better will help anyone model a good structure.

--Paul


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 5:42 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
does your association table contain extra properties or does it simply associate table1_id with table2_id?

if there are no extra info in this association table, the optimized object graph is a many to many, not a composite element.


I admit this doesn't solve the initial problem, it is just a tip

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 17, 2004 9:18 pm 
Newbie

Joined: Fri Jul 02, 2004 9:05 pm
Posts: 10
Yes, I agree: Simplify!

I completely eliminated the intermediate class, by mapping the set as follows:

Code:

        <set name="questionList" table="profile_properties" lazy="false">
          <key column="pid"/>
         <many-to-many column="qid" class="gov.alaska.ezdoc.ProfileQuestion" outer-join="true"/>
        </set>



I now obtain instances of ProfileQuestion from the questionList, and persistence works correctly.

Now when I compare a sample object against an instance, my equals method returns true, and my hashCode method returns the same value, but when I use questionlist.contains(sample), my hashCode method is evidently returning false. Here it is:

Code:
    public int hashCode() {
      System.out.println("ProfileQuestion.hashCode()");
        return new HashCodeBuilder(123,103).
         append(this.qid).
         append(this.type).
         append(this.question).
         toHashCode();
    }



This is a little off-topic, but germane to ensuring that a collection truly contains what I think it does. Any comments?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 18, 2004 3:20 am 
Expert
Expert

Joined: Fri Feb 06, 2004 7:49 am
Posts: 255
Location: Moscow, Russia
http://www.hibernate.org/109.html
HIA, chapter 4.1.6 Implementing equals() and hashCode()

In short, for implementing equals and hashCode use only business properties that compose natural key and don't use any synthetic primary and foreign keys. In your case qid is a synthetic key.

_________________
Leonid Shlyapnikov


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