我向apt stackflow社区倾诉并谦卑地寻求指导(我在写这篇文章时屈服于我的头脑)
我有以下Entity类/ bean,它混合了JPA / EclipseLink / JAXB / Moxy注释:( btw EventBase只是一个包含其他字段的@MappedSuperclass)
@Entity
@Table(name = "EVENTS")
@XmlRootElement
public class Event extends EventBase {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlAttribute(name = "id")
private long eventCID;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "APPLICATIONCID")
private CustomerApplication customerApplication;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CUSTOMERCID")
private Customer customer;
....
}
这是我的代码来编组这个实体(外部类为了简洁而排除)
public static void main(String args[]) {
Event event = myInstance.populateEvent();
myInstance.buildXMLFromEvent(event);
}
public Event populateEvent() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(this.persistenceUnit);
EntityManager em = null;
Event event = null;
try {
em = emf.createEntityManager();
event = (Event) em.createQuery("Select object(e) from Event e where e.eventCID = 55000").getSingleResult();
em.clear();
em.detach(event);
em.close();
em = null;
emf.close();
emf = null;
} catch (Exception e) { // just test code so catching general exception
log.error("Unexpected error: " + e);
} finally {
if (em != null) {
em.clear();
em.close();
}
}
return event;
}
private void buildXMLFromEvent(Event event) {
System.out.println("Marshalling now:");
JAXBContext jc;
try {
jc = JAXBContext.newInstance(Event.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.valueOf(true));
JAXBElement<Event> jaxbElement = new JAXBElement<Event>(new QName("event"), Event.class, event);
marshaller.marshal(jaxbElement, System.out);
} catch (JAXBException e) {
}
}
生成的xml实际上会急切地获取我的Event实体bean的所有成员对象!即客户,客户应用程序以及我为简洁而排除的任何其他映射.我使用EclipseLink作为我的JPA提供程序,使用Moxy作为JAXB.我在这做错了什么?您可以看到,不仅virtualManager和entityManagerFactory实例被清除,关闭并设置为null,而且我还继续分离根事件实体.而且,fetchtype已明确设置为LAZY!
当Event对象被分离时,JAXB如何急切地获取?我认为关闭entityManager本身会分离所有托管对象?是否有一些JAXB挂起的缓存会话上下文?如果是这样,为什么它甚至不尊重明确定义的获取策略?
提前谢谢了!
乌斯塔德阿
最佳答案 如果eclipselink处于独立模式,那么只有ManyToMany和OneToMany关系实际上使用延迟加载,对于其他关系,fetch属性被忽略并等于EAGER.
One-to-one: By default, EclipseLink JPA ignores the fetch attribute and
default javax.persistence.FetchType.EAGER applies.Many-to-one: EclipseLink JPA performs lazy loading when the fetch
attribute is set to javax.persistence.FetchType.LAZY.Basic: By default, EclipseLink JPA ignores the fetch attribute and
default javax.persistence.FetchType.EAGER applies.
这就是你的实体加载关系的原因.
希望能帮助到你.