4

我向 apt stackoverflow 社区鞠躬并谦虚地寻求指导(我在写这篇文章时低下头)

我有以下实体类/bean,它混合了 JPA/EclipseLink/JAXB/Moxy 注释:(顺便说一句,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 提供程序和用于 JAXB 的 Moxy。我在这里做错了什么?您可以看到,entityManager 和 entityManagerFactory 实例不仅被清除、关闭并设置为 null,而且我还继续分离了根 Event 实体。此外,fetchtype 已明确设置为 LAZY!

当 Event 对象被分离时,JAXB 是如何急切地获取的?我认为关闭 entityManager 本身会分离所有托管对象?是否有一些 JAXB 挂起的缓存会话上下文?如果是这样,为什么它甚至不遵守明确定义的获取策略?提前谢谢了!

乌斯塔德

4

1 回答 1

2

如果 eclipselink 处于独立模式,则只有 ManyToMany 和 OneToMany 关系实际上使用延迟加载,其他 fetch 属性被忽略并等于 EAGER。

这是http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basics的文档

一对一:默认情况下,EclipseLink JPA 忽略 fetch 属性,并应用默认 javax.persistence.FetchType.EAGER。

多对一:当 fetch 属性设置为 javax.persistence.FetchType.LAZY 时,EclipseLink JPA 执行延迟加载。

基本:默认情况下,EclipseLink JPA 忽略 fetch 属性并应用默认 javax.persistence.FetchType.EAGER。

这就是为什么您的实体加载了关系。

希望能帮助到你。

于 2012-08-26T18:09:23.130 回答