I am using OpenJPA 2.2.1 and ran into the following problem:
TypedQuery<OdpObjectScheduleEntity> q = em.createQuery(
"SELECT s FROM OdpObjectScheduleEntity s WHERE s.updateFreq IS NOT NULL",
OdpObjectScheduleEntity.class);
List<OdpObjectScheduleEntity> result = q.getResultList();
This is OdpObjectScheduleEntity
:
package ru.focusmedia.odp.server.datastore.jpa.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import ru.focusmedia.odp.server.datastore.api.objects.OdpObjectScheduleRecord;
@Entity
@Table(name = "object_schedules")
public class OdpObjectScheduleEntity implements OdpObjectScheduleRecord {
// fetch=FetchType.EAGER is the default.
// I've also tried explicitly setting it, no difference.
@OneToOne(optional = false)
@Column(nullable = false)
@Id
private OdpObjectEntity object;
@Column(name = "update_freq_seconds", nullable = true)
private Integer updateFreq;
protected OdpObjectScheduleEntity() {
// for JPA
}
public OdpObjectScheduleEntity(OdpObjectEntity object, Integer updateFreq) {
this.object = object;
this.updateFreq = updateFreq;
}
@Override
public OdpObjectEntity getObject() {
return object;
}
@Override
public Integer getUpdateFreq() {
return updateFreq;
}
public void setUpdateFreq(Integer updateFreq) {
this.updateFreq = updateFreq;
}
@Override
public String toString() {
return "OdpObjectScheduleEntity [object=" + object + ", updateFreq="
+ updateFreq + "]";
}
}
But the elements of the result
seem to look as if object is fetched lazily, e.g., OdpObjectScheduleEntity [object=OdpObjectEntity [id=23851, name=null, parent=null, odpClass=null], updateFreq=120]
. Am I missing something obvious or is this a bug in OpenJPA? I can work around this by doing something awful like
for (OdpObjectScheduleEntity schedule : result) {
// simply schedule.getObject() doesn't work
schedule.getObject().toString();
}
Is there a better way to force loading the relationship?
I haven't ever used OpenJPA, so I cannot tell you what's exactly wrong, but you could try using JOIN FETCH
:
TypedQuery<OdpObjectScheduleEntity> q = em.createQuery(
"SELECT s FROM OdpObjectScheduleEntity s LEFT JOIN FETCH s.object WHERE s.updateFreq IS NOT NULL",
OdpObjectScheduleEntity.class);
List<OdpObjectScheduleEntity> result = q.getResultList();
For more information, see for example http://docs.oracle.com/html/E24396_01/ejb3_langref.html#ejb3_langref_fetch_joins