5 Replies Latest reply on Aug 10, 2006 11:04 AM by Krol Przem

    Lazy loading for OneToOne association (entities share the sa

    Andrej Kovcic Newbie

      Hello,

      I can't make one-to-one association lazy in case when entities share the same primary key. For the case when foreign key is held by one of the entities it works fine. Maybe I miss something. Here is the setup:

      Entity A
      |
      +---> Entity B (by FK)
      |
      +---> Entity C (shared PK)

      Here is the code of Entities A, B, C

      @Entity
      @Table(name = "T_TEST_A")
      public class EntityA implements Serializable {
      
       private int id;
       private String description;
       private EntityB entityB;
       private EntityC entityC;
      
       public EntityA() {
       }
      
       /**
       * @return Returns the id.
       */
       @Id
       @Column(name = "ID")
       public int getId() {
       return id;
       }
      
       /**
       * @param id The id to set.
       */
       public void setId(int id) {
       this.id = id;
       }
      
       /**
       * @return Returns the description.
       */
       @Column(name = "DESCRIPTION")
       public String getDescription() {
       return description;
       }
      
       /**
       * @param description The description to set.
       */
       public void setDescription(String description) {
       this.description = description;
       }
      
       /**
       * @return Returns the entityB.
       */
       @OneToOne(fetch = FetchType.LAZY)
       @JoinColumn(name = "B_ID")
       public EntityB getEntityB() {
       return entityB;
       }
      
       /**
       * @param entityB The entityB to set.
       */
       public void setEntityB(EntityB entityB) {
       this.entityB = entityB;
       }
      
       /**
       * @return Returns the entityC.
       */
       @OneToOne(fetch = FetchType.LAZY)
       @PrimaryKeyJoinColumn
       public EntityC getEntityC() {
       return entityC;
       }
      
       /**
       * @param entityC The entityC to set.
       */
       public void setEntityC(EntityC entityC) {
       this.entityC = entityC;
       }
      
       @Override
       public String toString() {
       return "EntityA[id = " + id + ", description = " + description + "]";
       }
      
      }
      
      


      @Entity
      @Table(name = "T_TEST_B")
      public class EntityB {
      
       private int id;
       private String description;
      
       public EntityB() {
       }
      
       /**
       * @return Returns the id.
       */
       @Id
       @Column(name = "ID")
       public int getId() {
       return id;
       }
      
       /**
       * @param id The id to set.
       */
       public void setId(int id) {
       this.id = id;
       }
      
       /**
       * @return Returns the description.
       */
       @Column(name = "DESCRIPTION")
       public String getDescription() {
       return description;
       }
      
       /**
       * @param description The description to set.
       */
       public void setDescription(String description) {
       this.description = description;
       }
      
       @Override
       public String toString() {
       return "EntityB[id = " + id + ", description = " + description + "]";
       }
      
      }
      


      @Entity
      @Table(name = "T_TEST_C")
      public class EntityC {
      
       private int id;
       private String description;
      
       public EntityC() {
       }
      
       /**
       * @return Returns the id.
       */
       @Id
       @Column(name = "ID")
       public int getId() {
       return id;
       }
      
       /**
       * @param id The id to set.
       */
       public void setId(int id) {
       this.id = id;
       }
      
       /**
       * @return Returns the description.
       */
       @Column(name = "DESCRIPTION")
       public String getDescription() {
       return description;
       }
      
       /**
       * @param description The description to set.
       */
       public void setDescription(String description) {
       this.description = description;
       }
      
       @Override
       public String toString() {
       return "EntityC[id = " + id + ", description = " + description + "]";
       }
      
      }
      


      Extract from the test case that fails:

       public void testExecutionFormatLookup() throws Exception {
       EntityManager em = getEntityManager();
       TransactionManager tm = getTransactionManger();
      
       try {
       tm.begin();
      
       EntityA ea = em.find(EntityA.class, new Integer(1));
       assertNotNull(ea);
      
       assertFalse("Entity B is initalized", Hibernate.isInitialized(ea.getEntityB()));
       assertFalse("Entity C is initalized", Hibernate.isInitialized(ea.getEntityC())); // FAILS!!!
      
       log.info("Selected entity: " + ea);
       }
       finally {
       tm.commit();
       }
       }
      


      I see two selects executed on find(). One loads entity A, and another laods and initializes association to entity C:

      Hibernate: select entitya0_.ID as ID88_0_, entitya0_.B_ID as B3_88_0_, entitya0_.DESCRIPTION as DESCRIPT2_88_0_ from T_TEST_A entitya0_ where entitya0_.ID=?
      Hibernate: select entityc0_.ID as ID90_0_, entityc0_.DESCRIPTION as DESCRIPT2_90_0_ from T_TEST_C entityc0_ where entityc0_.ID=?
      


      The structure of tables is rather simple:
      T_TEST_A: ID (PK), DESCRIPTION, B_ID (FK to T_TEST_B.ID)
      T_TEST_B: ID (PK), DESCRIPTION
      T_TEST_C: ID (PK), DESCRIPTION

      Using jboss embeddable when junit testing:
      12:33:38,461 INFO [Version] Hibernate EntityManager 3.2.0.CR1
      12:33:38,476 INFO [Version] Hibernate Annotations 3.2.0.CR1
      12:33:38,492 INFO [Environment] Hibernate 3.2 cr2
      12:33:38,492 INFO [Environment] hibernate.properties not found
      12:33:38,507 INFO [Environment] Bytecode provider name : cglib
      12:33:38,539 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling
      ....
      


      What to do to make association to entity C lazy loadable?
      Tahnks for help.