OpenJPA - lazy selection not working

I have a specific problem with a unit test using the built-in OpenEJB container. I have a bi-directional communication between two classes. In one direction, the ratio works correctly, but in the opposite direction, the ratio only works in EAGER mode. In LAZY mode, the field section

remains zero. Below is the code:

@Entity
@Table(name="tracks")
class TrackEntity implements Track {
    @Id
    private int trackNumber;
    @OneToMany(mappedBy = "track")
    private HashSet<SectionEntity> sections;

    public TrackEntity() {
        sections = new HashSet<SectionEntity>();
    }

    @Override
    public Collection<HistoricalEvent> getEvents() {
        if (sections == null)
            throw new CommonError("number=" + trackNumber, AppErrors.TRACK_EMPTY);

        TreeSet<HistoricalEvent> set = new TreeSet<HistoricalEvent>();
        for (SectionEntity se : sections)
            set.addAll(se.getEvents());

        return set;
    }
 }

      

My code is a little bit specific. The class uses the field sections

only internally to combine all subcategories. I cannot fill the sections lazily. I think the container expects the client to access the field from the outside via a getter.

0


source to share


1 answer


Its a lifecycle problem. All enties (track and its sections) must be bound to the persistence context. The event collection method must be in the class using EntityManager

. (An entity cannot use a manager to reattach.) An example of an updated entity management class follows:

public class EntityDataAccessor {
    @PersistenceUnit(unitName = "someUnit")
    private EntityManagerFactory emFactory;

    //gets one track
    public Track getTrack(int number) {
        EntityManager em = emFactory.createEntityManager();
        try {
            return (Track)em.find(TrackEntity.class, number);
        }
        finally {
            em.close();
        }
    }

    //the new method collecting events
    public Collection<HistoricalEvent> getEventsForTrack(TrackEntity te) {
        EntityManager em = emFactory.createEntityManager();
        te = em.merge(te); //re-attach to the context

        Set<SectionEntity> sections = te.getSections();
        TreeSet<HistoricalEvent> set = new TreeSet<HistoricalEvent>();
        for (SectionEntity se : sections) {
            se = em.merge(se); //re-attach to the context
            set.addAll(se.getEvents());
        }
        em.close();
        return set;
    }
}

      



See the question What is a lazy strategy and how does it work? for more details.

+2


source







All Articles