-->
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.  [ 2 posts ] 
Author Message
 Post subject: Criteria and one-to-one lazy association
PostPosted: Tue Aug 19, 2008 11:33 am 
Newbie

Joined: Tue Aug 19, 2008 11:13 am
Posts: 2
Location: Argentina
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


Top
 Profile  
 
 Post subject: going deeper
PostPosted: Wed Aug 20, 2008 5:47 pm 
Newbie

Joined: Tue Aug 19, 2008 11:13 am
Posts: 2
Location: Argentina
I don't understand how it works...

If I use
Code:
session.load(ClassA.class, id);
it works lazy.

But if I use
Code:
session.get(ClassA.class, id);
or criteria it doesn't work lazy.

Debbuging I've seen that in the method DefaultLoadEventListener.proxyOrLoad(..) it asks if it's allow proxy creation.

Code:
/** options is a final class LoadType.
* if you call session.load -> LoadEventListener.LOAD
* if you call session.get -> LoadEventListener.GET
*/
            if ( options.isAllowProxyCreation() ) {
               return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext );
            }
            else {
               // return a newly loaded object
               return load(event, persister, keyToLoad, options);
            }


There is where LoadEventListener.LOAD allows proxy and LoadEventListener.GET doesn't allow.


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