I have the following classes:
PartyCode:
@Entity
@Table(name = "Party")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Party implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private long version;
private long id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Version
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
@Id
@Column(name = "partyId")
@GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
PartyRoleCode:
@Entity
@Table(name = "PartyRole")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class PartyRole implements Serializable {
private static final long serialVersionUID = 1L;
private long version;
private long id;
private Party party;
@Version
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
@JoinColumn(name = "PartyId", nullable = false)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
public Party getParty() {
return party;
}
public void setParty(Party party) {
this.party = party;
}
@Id
@Column(name = "partyRoleId")
@GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
CustomerCode:
@Entity
public class Customer extends PartyRole implements Serializable {
private static final long serialVersionUID = 1L;
private String accountNumber;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
}
I've enabled 2nd level cache and am also using query caches.
I load a collection of Customer instances using the following query (I call setHint on query to ensure that Hibernate caches the results):
Code:
"select c from " + Customer.class.getName() + " c left join fetch c.party"
Now, when I execute this query the second time, I get an exception:
Code:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:191)
tests.crm.Party_$$_javassist_2.getName(Party_$$_javassist_2.java)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
I have two questions:
1. Why is Hibernate setting the value of Party to a proxy even when I'm eagerly loading it using join fetch?
2. Why is the proxy being put in the cache instead of real Party?
This is with Hibernate 3.5.5 Final.
The curious thing is that if I keep a session open so when the query is executed 2nd time, everything works as expected i.e. no call is made to the database as Hibernate loads Party from cache.