问题描述
使用嵌入式OpenEJB容器进行单元测试时,我遇到一个特定的问题.我在两个班级之间有双向关系.在一个方向上,该关系正常工作,但在相反的方向上,该关系仅在EAGER模式下有效.在LAZY模式下,字段section
保持为空.代码片段如下:
I have a specific problem with an unit test using embedded OpenEJB container. I have a bi-directional relation between two classes. In one direction the relation works properly, but in the opposite direction the relation works only in EAGER-mode. In LAZY-mode the field section
stays null. The code snipped follows:
@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从外部访问该字段.
My code is little bit specific. The class uses the field sections
just internally to merge all sub-collections. I'm unable to fill sections lazily. I thing, the container expects client to access the field externally via a getter.
推荐答案
这是实体生命周期的问题.必须将所有实体(轨道及其部分)重新附加到持久性上下文.收集事件的方法必须在使用EntityManager
的类中. (实体不能使用管理器来重新附加自身.)更新的实体管理类的示例如下:
Its the problem with life cycle of enties. All enties (track and its sections) must be re-attached to the persistence context. The method collecting events must be in the class using EntityManager
. (The entity cannot use the manager to re-attach itself.) Example of updated entity managing 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 question What's the lazy strategy and how does it work? for more detail.
这篇关于OpenJPA-延迟获取不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!