I have some problems configuring a one-to-one relationship between two classes.
I've read few topics in the forum and the FAQ, but I can't sort out it.
When I use load to get the class by its id it works as expected (lazy), but if I use Criteria by id or get it goes for the other class (marked as lazy).
How could I solve it? Is this a bug or I'm doing something brong?
Here's the mapping and code...
Hibernate 3.3.0.GA
Code:
   <class name="ar.com.test.ClassA" table="TEST_CLASS_A" lazy="true">
      <id name="id" column="ID">
         <generator class="sequence">
            <param name="sequence">SEQ_ID_CLASS_A</param>
         </generator>
      </id>
        <one-to-one name="classC" 
            outer-join="false" 
            class="ar.com.test.ClassC" 
            lazy="proxy"
            fetch="select"
            constrained="true" 
            property-ref="classA" />
   </class>
   <class name="ar.com.test.ClassC" table="TEST_CLASS_C" lazy="true">
      <id name="id" column="ID">
         <generator class="sequence">
            <param name="sequence">SEQ_ID_CLASS_C</param>
         </generator>
      </id>
      <many-to-one name="classA" 
        class="ar.com.test.ClassA" 
        column="CLASS_A_ID" 
        unique="true"
        cascade="all" 
        not-null="true" 
        lazy="proxy" 
        fetch="select"
        />
   </class>
/** class a **/
public class ClassA {
   private Integer id;
   private ClassC classC;
   
   public Integer getId() {
      return id;
   }
   public void setId(Integer id) {
      this.id = id;
   }
   public ClassC getClassC() {
      return classC;
   }
   public void setClassC(ClassC classC) {
      this.classC = classC;
   }
   
}
/** class c **/
public class ClassC {
   private Integer id;
   private ClassA classA;
   
   public Integer getId() {
      return id;
   }
   public void setId(Integer id) {
      this.id = id;
   }
   public ClassA getClassA() {
      return classA;
   }
   public void setClassA(ClassA classA) {
      this.classA = classA;
   }
   
}
/** DAO **/
public class ClassDao extends HibernateDaoSupport {
   
   public ClassA loadClassA(Integer id) {
      return (ClassA) getHibernateTemplate().load(ClassA.class, id);
   }
   
   public ClassC loadClassC(Integer id) {
      return (ClassC) getHibernateTemplate().load(ClassC.class, id);
   }
   
   @SuppressWarnings("unchecked")
    public List<ClassA> findClassAByIdsList(final List<Integer> idsList) {
        return getHibernateTemplate().executeFind(new HibernateCallback() {
         public Object doInHibernate(Session session)
               throws HibernateException, SQLException {
            Criteria criteria = session
                  .createCriteria(ClassA.class);
            criteria.add(Restrictions.in("id", idsList));
            criteria.addOrder(Order.asc("id"));
            return criteria.list();
         }
      });
    }
   
   @SuppressWarnings("unchecked")
    public List<ClassA> findClassCByIdsList(final List<Integer> idsList) {
        return getHibernateTemplate().executeFind(new HibernateCallback() {
         public Object doInHibernate(Session session)
               throws HibernateException, SQLException {
            Criteria criteria = session
                  .createCriteria(ClassC.class);
            criteria.add(Restrictions.in("id", idsList));
            criteria.addOrder(Order.asc("id"));
            return criteria.list();
         }
      });
    }
/** Test **/
public class ClassDaoTest extends AbstractTransactionalSpringContextTests {
   protected ClassDao classDao;
   public ClassDaoTest(String name) {
      super(name);
      setPopulateProtectedVariables(true);
   }
   
   public void testLoadA() {
      ClassA classA = classDao.loadClassA(Integer.valueOf(4));
      assertNotNull(classA);
      assertEquals(Integer.valueOf(4), classA.getId());
      assertTrue("ClassC initialized", 
            !Hibernate.isPropertyInitialized(classA, "classC"));
   }
   
   public void testLoadC() {
      ClassC classC = classDao.loadClassC(Integer.valueOf(3));
      assertNotNull(classC);
      assertEquals(Integer.valueOf(3), classC.getId());
      assertTrue("ClassA initialized", 
            !Hibernate.isPropertyInitialized(classC, "classA"));
   }
   
   public void testFindA() {
      List<Integer> idsList = new ArrayList<Integer>();
      idsList.add(4);
      idsList.add(5);
      List<ClassA> listClassA = classDao.findClassAByIdsList(idsList);
      assertNotNull(listClassA);
      assertEquals(true, listClassA.size() > 0);
      for(ClassA classA : listClassA) {
         assertTrue("ClassC initialized", 
               !Hibernate.isPropertyInitialized(classA, "classC"));
      }
   }
   
   public void testFindC() {
      List<Integer> idsList = new ArrayList<Integer>();
      idsList.add(3);
      idsList.add(4);
      List<ClassA> listClassA = classDao.findClassAByIdsList(idsList);
      assertNotNull(listClassA);
      assertEquals(true, listClassA.size() > 0);
      for(ClassA classA : listClassA) {
         assertTrue("ClassA initialized", 
               !Hibernate.isPropertyInitialized(classA, "classC"));
      }
   }   
   
   @Override
   protected String[] getConfigLocations() {
      return new String[] {
            "classpath:test-properties-spring.xml",
            "classpath:test-datasource.xml",
            "classpath:test-persistence.xml",
            "classpath:test-hibernate-class-mappings.xml",
            "classpath:test-hibernate-properties.xml",               
            "classpath:test-transaction-manager.xml", 
            "classpath:test-class-dao.xml"};
   }
   
}
And the log from the junit test:
Code:
  12:27:00,703 INFO  [ClassDaoTest] Loading context for locations: classpath:test-properties-spring.xml,classpath:test-datasource.xml,classpath:test-persistence.xml,classpath:test-hibernate-class-mappings.xml,classpath:test-hibernate-properties.xml,classpath:test-transaction-manager.xml,classpath:test-class-dao.xml
SLF4J: This version of SLF4J requires log4j version 1.2.12 or later. See also http://www.slf4j.org/codes.html#log4j_version
  12:27:02,656 INFO  [Environment] Hibernate 3.3.0.GA
  12:27:02,671 INFO  [Environment] loaded properties from resource hibernate.properties: {hibernate.cglib.use_reflection_optimizer=true, hibernate.bytecode.use_reflection_optimizer=false}
  12:27:02,671 WARN  [Environment] Property [hibernate.cglib.use_reflection_optimizer] has been renamed to [hibernate.bytecode.use_reflection_optimizer]; update your properties appropriately
  12:27:02,671 INFO  [Environment] Bytecode provider name : javassist
  12:27:02,687 INFO  [Environment] using JDK 1.4 java.sql.Timestamp handling
  12:27:03,140 INFO  [HbmBinder] Mapping class: ar.com.test.ClassA -> TEST_CLASS_A
  12:27:03,234 INFO  [HbmBinder] Mapping class: ar.com.test.ClassC -> TEST_CLASS_C
  12:27:03,359 WARN  [Environment] Property [hibernate.cglib.use_reflection_optimizer] has been renamed to [hibernate.bytecode.use_reflection_optimizer]; update your properties appropriately
  12:27:03,375 INFO  [ConnectionProviderFactory] Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
  12:27:04,171 INFO  [SettingsFactory] RDBMS: DB2/HP64, version: SQL08026
  12:27:04,171 INFO  [SettingsFactory] JDBC driver: IBM DB2 JDBC Universal Driver Architecture, version: 3.1.57
  12:27:04,312 INFO  [Dialect] Using dialect: ar.com.osde.wf.utils.OptimizedDB2Dialect
  12:27:04,328 INFO  [TransactionFactoryFactory] Using default transaction strategy (direct JDBC transactions)
  12:27:04,328 INFO  [TransactionManagerLookupFactory] No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
  12:27:04,328 INFO  [SettingsFactory] Automatic flush during beforeCompletion(): disabled
  12:27:04,328 INFO  [SettingsFactory] Automatic session close at end of transaction: disabled
  12:27:04,343 INFO  [SettingsFactory] Scrollable result sets: enabled
  12:27:04,343 INFO  [SettingsFactory] JDBC3 getGeneratedKeys(): enabled
  12:27:04,343 INFO  [SettingsFactory] JDBC result set fetch size: 100
  12:27:04,343 INFO  [SettingsFactory] Connection release mode: on_close
  12:27:04,343 INFO  [SettingsFactory] Default schema: DBWFGEND_1_4
  12:27:04,343 INFO  [SettingsFactory] Default batch fetch size: 1
  12:27:04,343 INFO  [SettingsFactory] Generate SQL with comments: enabled
  12:27:04,343 INFO  [SettingsFactory] Order SQL updates by primary key: disabled
  12:27:04,343 INFO  [SettingsFactory] Order SQL inserts for batching: disabled
  12:27:04,343 INFO  [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
  12:27:04,343 INFO  [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory
  12:27:04,343 INFO  [SettingsFactory] Query language substitutions: {}
  12:27:04,343 INFO  [SettingsFactory] JPA-QL strict compliance: disabled
  12:27:04,343 INFO  [SettingsFactory] Second-level cache: enabled
  12:27:04,343 INFO  [SettingsFactory] Query cache: enabled
  12:27:04,359 INFO  [SettingsFactory] Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
  12:27:04,359 INFO  [RegionFactoryCacheProviderBridge] Cache provider: ar.com.osde.wf.core.cache.impl.EhCacheProvider
  12:27:04,359 INFO  [SettingsFactory] Optimize cache for minimal puts: disabled
  12:27:04,359 INFO  [SettingsFactory] Structured second-level cache entries: disabled
  12:27:04,359 INFO  [SettingsFactory] Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
  12:27:04,375 INFO  [SettingsFactory] Statistics: enabled
  12:27:04,375 INFO  [SettingsFactory] Deleted entity synthetic identifier rollback: disabled
  12:27:04,375 INFO  [SettingsFactory] Default entity-mode: pojo
  12:27:04,375 INFO  [SettingsFactory] Named query checking : enabled
  12:27:04,468 INFO  [SessionFactoryImpl] building session factory
  12:27:05,171 INFO  [SessionFactoryObjectFactory] Not binding factory to JNDI, no JNDI name configured
  12:27:05,171 INFO  [UpdateTimestampsCache] starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
  12:27:05,187 INFO  [StandardQueryCache] starting query cache at region: org.hibernate.cache.StandardQueryCache
  12:27:05,312 WARN  [ClassDaoTest] No bean with name 'transactionStatus'
  12:27:05,421 INFO  [ClassDaoTest] Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@6835fb]; default rollback = true
  12:27:05,468 INFO  [ClassDaoTest] Rolled back transaction after test execution
  12:27:05,468 WARN  [ClassDaoTest] No bean with name 'transactionStatus'
  12:27:05,484 INFO  [ClassDaoTest] Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@6835fb]; default rollback = true
  12:27:05,484 INFO  [ClassDaoTest] Rolled back transaction after test execution
  12:27:05,484 WARN  [ClassDaoTest] No bean with name 'transactionStatus'
  12:27:05,484 INFO  [ClassDaoTest] Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@6835fb]; default rollback = true
  12:27:05,609 DEBUG [SQL] 
    /* criteria query */ select
        this_.ID as ID0_0_ 
    from
        DBWFGEND_1_4.TEST_CLASS_A this_ 
    where
        this_.ID in (
            ?, ?
        ) 
    order by
        this_.ID asc
  12:27:05,796 DEBUG [IntegerType] binding '4' to parameter: 1
  12:27:05,812 DEBUG [IntegerType] binding '5' to parameter: 2
  12:27:05,859 DEBUG [IntegerType] returning '4' as column: ID0_0_
  12:27:05,859 DEBUG [IntegerType] returning '5' as column: ID0_0_
  12:27:05,875 DEBUG [SQL] 
    /* load ar.com.test.ClassC */ select
        classc0_.ID as ID1_0_,
        classc0_.CLASS_A_ID as CLASS2_1_0_ 
    from
        DBWFGEND_1_4.TEST_CLASS_C classc0_ 
    where
        classc0_.CLASS_A_ID=?
  12:27:05,875 DEBUG [IntegerType] binding '4' to parameter: 1
  12:27:05,875 DEBUG [IntegerType] returning '3' as column: ID1_0_
  12:27:05,968 DEBUG [IntegerType] returning '4' as column: CLASS2_1_0_
  12:27:05,968 DEBUG [SQL] 
    /* load ar.com.test.ClassC */ select
        classc0_.ID as ID1_0_,
        classc0_.CLASS_A_ID as CLASS2_1_0_ 
    from
        DBWFGEND_1_4.TEST_CLASS_C classc0_ 
    where
        classc0_.CLASS_A_ID=?
  12:27:05,968 DEBUG [IntegerType] binding '5' to parameter: 1
  12:27:05,968 DEBUG [IntegerType] returning '4' as column: ID1_0_
  12:27:05,968 DEBUG [IntegerType] returning '5' as column: CLASS2_1_0_
  12:27:05,968 INFO  [ClassDaoTest] Rolled back transaction after test execution
  12:27:05,984 WARN  [ClassDaoTest] No bean with name 'transactionStatus'
  12:27:05,984 INFO  [ClassDaoTest] Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@6835fb]; default rollback = true
  12:27:05,984 DEBUG [SQL] 
    /* criteria query */ select
        this_.ID as ID0_0_ 
    from
        DBWFGEND_1_4.TEST_CLASS_A this_ 
    where
        this_.ID in (
            ?, ?
        ) 
    order by
        this_.ID asc
  12:27:06,015 DEBUG [IntegerType] binding '3' to parameter: 1
  12:27:06,015 DEBUG [IntegerType] binding '4' to parameter: 2
  12:27:06,015 DEBUG [IntegerType] returning '4' as column: ID0_0_
  12:27:06,015 DEBUG [SQL] 
    /* load ar.com.test.ClassC */ select
        classc0_.ID as ID1_0_,
        classc0_.CLASS_A_ID as CLASS2_1_0_ 
    from
        DBWFGEND_1_4.TEST_CLASS_C classc0_ 
    where
        classc0_.CLASS_A_ID=?
  12:27:06,015 DEBUG [IntegerType] binding '4' to parameter: 1
  12:27:06,031 DEBUG [IntegerType] returning '3' as column: ID1_0_
  12:27:06,031 DEBUG [IntegerType] returning '4' as column: CLASS2_1_0_
  12:27:06,031 INFO  [ClassDaoTest] Rolled back transaction after test execution
  12:27:06,031 INFO  [SessionFactoryImpl] closing