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.