-->
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.  [ 1 post ] 
Author Message
 Post subject: Proxied one-to-one on PK doesn't initialize
PostPosted: Thu Apr 20, 2006 8:49 am 
Beginner
Beginner

Joined: Wed Jul 13, 2005 2:18 pm
Posts: 44
I've got a unidirectional one-to-one relationship on a primary key, configured as per the documentation. In other words, for every instance of object A there exists an object B with a primary key identical to that of the A instance. Instances of object B hold references to their corresponding instances of object A, but not the other way around.

I have found that when I query for object B without doing a fetch join on object A and then access A's fields through the reference on B, the proxy both fails to initialize itself and fails to indicate an error. In fact, when accessing the primary key of A through the reference on B (which is an integer), the proxy simply returns 0.

Hibernate version: 3.0.5

Mapping documents:
Note that attributes unrelated to the problem being discussed have been stripped out for clarity.

Object 'A':
Code:
<hibernate-mapping package="edu.taylor.facade.employee">
   <class name="IappEmployee" table="employee">
      <id name="pidm" access="field">
         <generator class="assigned"/>
      </id>
      
      <property name="firstName"/>
      <property name="lastName"/>
      
      <one-to-one name="contactInfoListing" class="IappContactInfoListing"
         access="edu.taylor.facade.NonExistentPropertyAccessor" />
   </class>
</hibernate-mapping>


And now you're gonna say: "Hey jerk, you said it was a unidirectional relationship...and what the heck is a NonExistentPropertyAccessor??" To be honest, I'd rather not get into it, and I'm reasonably sure that it isn't related to my question. The short version is it makes certain HQL queries a lot less awkward.

Object 'B':
Code:
<hibernate-mapping package="edu.taylor.facade.employee">
   <class name="IappContactInfoListing" table="contact_info_listing">
      <id column="pidm" type="integer">
         <generator class="foreign">
            <param name="property">employee</param>
         </generator>
      </id>

      <one-to-one name="employee"   class="IappEmployee" constrained="true" access="field"/>
      <property name="email"/>
   </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
I'm using Spring, and I noticed this behavior while writing a FitNesse test, so this code might look a little confusing. Basically, I'm wrapping each instance of IappContactInfoListing in a thin wrapper class so that FitNesse can verify the contents of each class. FitNesse is a wiki-based tool for writing executable user acceptance tests, in case you're insterested.

Code:
   public Set<ContactInfoListingVerifier> verifyContactInfoListings() {
      TransactionTemplate txTemplate = new TransactionTemplate();
      txTemplate.setTransactionManager((PlatformTransactionManager)ctx.getBean("txManager"));
      return (Set<ContactInfoListingVerifier>)txTemplate.execute(new TransactionCallback() {
         public Object doInTransaction(TransactionStatus arg0) {
            Set<ContactInfoListingVerifier> wrappedResults = new HashSet<ContactInfoListingVerifier>();
            List<IappContactInfoListing> results = hibernate.find(
            "from IappContactInfoListing l ");
            for (IappContactInfoListing l : results) {
               wrappedResults.add(new ContactInfoListingVerifier(l));
            }
            return wrappedResults;
         }
      });
   }


Here's the code for the wrapper class. Once again, irrelevent attributes have been stripped for simplicity.
Code:
   public class ContactInfoListingVerifier {
      public int employeePidm;
      
      public ContactInfoListingVerifier(ContactInfoListing listing) {
         logger.debug("Employee instance: " + listing.getEmployee());
         employeePidm = listing.getEmployee().getPidm();
      }


Now, each wrapper returned by the above code has an employeePidm of 0. This is most certainly not what is stored in the DB - in the first place I've checked that the correct values are stored, and in the second, it's a primary key field!

If I change the HQL query to include a fetch join on l.employee, then the code above works as expected without any modifications. That raises a warning bell for me - unless I've broken something in the configuration, adding a fetch join should result in either no change, or a LazyInitializationException if the session has closed, but that's about it right?

Name and version of the database you are using:
SQL Server 2000

_________________
- Matt


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

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.