【问题标题】:OpenJPA - lazy fetching does not workOpenJPA - 延迟获取不起作用
【发布时间】:2011-10-15 10:15:35
【问题描述】:

我在使用嵌入式 OpenEJB 容器进行单元测试时遇到了一个特定问题。我在两个类之间有双向关系。在一个方向上,关系正常工作,但在相反方向上,关系仅在 EAGER 模式下工作。在 LAZY 模式下,section 字段保持为空。截取的代码如下:

@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;
    }
 }

我的代码有点具体。该类仅在内部使用字段sections 来合并所有子集合。我无法懒惰地填写部分。我的意思是,容器希望客户端通过 getter 从外部访问该字段。

【问题讨论】:

  • 我已经使用名为 externtaly(直接来自测试类)的公共 getter 对另外两个类进行了一个简单的示例,但如果策略是 LAZY,它也总是返回 null。我认为问题出在嵌入式容器中。
  • 这似乎是 OpenEJB 的一个特性。我将在生产环境中尝试该应用程序(在带有 Geronimo 容器的测试服务器上),我希望我能了解更多。

标签: jpa fetch openjpa


【解决方案1】:

这是实体生命周期的问题。所有实体(轨道及其部分)必须重新附加到持久性上下文。收集事件的方法必须在使用EntityManager 的类中。 (实体不能使用管理器重新连接自己。)更新的实体管理类示例如下:

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;
    }
}

更多详情请参阅问题What's the lazy strategy and how does it work?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    相关资源
    最近更新 更多