Search code examples
jpaopenjpa

OpenJPA doesn't fetch OneToOne relationship


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?


Solution

  • 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