jpa - 即使 EntityManager 已被清除()、关闭()并设置为 null,JAXB 也会急切地获取标记为 FetchType.LAZY 的字段

标签 jpa jaxb lazy-loading eclipselink moxy

我向 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 的所有成员对象!即)Customer、CustomerApplication 以及为简洁起见而排除的任何其他映射。我使用 EclipseLink 作为我的 JPA 提供程序,并使用 Moxy 作为 JAXB。我在这里做错了什么?您可以看到,不仅entityManager 和entityManagerFactory 实例被清除、关闭并设置为null,而且我还继续分离了根Event 实体。而且,fetchtype 已明确设置为 LAZY!

当事件对象已分离时,JAXB 是如何快速获取的?我认为关闭entityManager本身会分离所有托管对象? JAXB 是否挂有一些缓存的 session 上下文?如果是这样,为什么它甚至不遵守明确定义的获取策略? 非常感谢!

乌斯塔德

最佳答案

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

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

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.

这就是您的实体加载关系的原因。

希望有帮助。

关于jpa - 即使 EntityManager 已被清除()、关闭()并设置为 null,JAXB 也会急切地获取标记为 FetchType.LAZY 的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12111288/

相关文章:

java - 为什么我不能在这里创建外键?错误 1215 (HY000) : Cannot add foreign key constraint

spring - 如何配置spring批处理不自动创建用于存储元数据的批处理表?

java - 使用 JAXB 的 XML 中的 header 标记

python - 在 sqlalchemy 中延迟加载列

javascript - 使用 Backbone 进行延迟加载

java - 带有 JPA 的 MySQL 中的 Precision Java Float (EclipseLink)

java - 使用@Singleton 和@Stateless 加载和缓存应用程序范围的数据

jaxb - 如何忽略父类中的 JAXB 注释属性?

java - 如何使用 JAXB 将自定义 "type"属性添加到我的 XML 中?

hibernate - 如何在使用 Hibernate 映射的类中实现 toString()?