Lazy loading for OneToOne association (entities share the sa
akovcic Aug 3, 2006 6:52 AMHello,
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.