为什么JPA的FetchType.LAZY不起作用?

时间:2011-12-14 14:10:08

标签: jpa eclipselink

JPA提供商eclipselink 2.3 AS glassfish 3.1.1 B12 用于远程调用的二进制协议Hessian

服务器端ejb + jpa 客户端Plain Swing。

JPA映射

@Entity
@Table(name = "FATHER", catalog = "CAT", schema = "dbo")
public class Father implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(generator = "FATHERUID", strategy = GenerationType.TABLE)
    @TableGenerator(name = "FATHERUID", table = "FAMILY_UID", catalog = "LSDB", schema = "dbo", pkColumnName = "PRIM", pkColumnValue = "father_uid", valueColumnName = "UID", allocationSize = 1, initialValue = 0)
    private Long id;

    @OneToOne(mappedBy = "father", fetch = FetchType.LAZY)
    private Mother mother;

    @OneToMany(mappedBy = "father", fetch = FetchType.LAZY)
    private List<Friend> friendList;

}


@Entity
@Table(name = "FRIEND", catalog = "CAT", schema = "dbo")
@NamedQueries({
    @NamedQuery(name = "Friend.findAll", query = "SELECT f FROM Friend f")})
public class Friend implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(generator = "FRIENDUID", strategy = GenerationType.TABLE)
    @TableGenerator(name = "FRIENDUID", table = "FAMILY_UID", catalog = "LSDB", schema = "dbo", pkColumnName = "PRIM", pkColumnValue = "friend_uid", valueColumnName = "UID", allocationSize = 1, initialValue = 0)
    private Long id;

    @JoinColumn(name = "FATHERID", referencedColumnName = "ID")
    @ManyToOne(optional = false,fetch= FetchType.LAZY)
    private Father father;

}

EJB方法

   public Father findFather(long id) {

        Father fath = em.find(Father.class, id);

        PersistenceUnitUtil util = em.getEntityManagerFactory().getPersistenceUnitUtil();

        System.out.println("mother isloaded="+util.isLoaded(fath,"mother"));
        System.out.println("friendList isloaded="+util.isLoaded(fath,"friendList"));

        return fath;
    }

客户端调用Hessian

   public void findFather() {

        try {

        IManager manager = ProxyHelper.getStub();
       //find by father id
        Father father = manager.findFather(3500L);

        System.out.println("Father=" + father);
        System.out.println("father's friends=" + father.getFriendList());
        System.out.println("mother=" + father.getMother());

  } catch (MalformedURLException ex) {

  }

 }

一切正常,但是当我发现查看服务器日志和父实体相关方时 从数据库填充LazyLoaded anotated字段。

服务器日志

FINEST: Begin deploying Persistence Unit test; session file:/C:/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test; state Predeployed; factoryCount 1
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
FINEST: property=eclipselink.target-server; value=SunAS9; translated value=org.eclipse.persistence.platform.server.sunas.SunAS9ServerPlatform
FINEST: property=eclipselink.logging.level; value=FINEST; translated value=FINEST
FINEST: property=eclipselink.logging.parameters; value=true
FINEST: property=eclipselink.logging.level; value=FINEST; translated value=FINEST
FINEST: property=eclipselink.logging.parameters; value=true
FINEST: property=eclipselink.cache.shared.default; value=false; translated value=false
INFO: EclipseLink, version: Eclipse Persistence Services - 2.3.2.v20111125-r10461
FINEST: Database platform: org.eclipse.persistence.platform.database.oracle.Oracle11Platform, regular expression: (?i)oracle.*11
FINEST: Database platform: org.eclipse.persistence.platform.database.oracle.Oracle10Platform, regular expression: (?i)oracle.*10
FINEST: Database platform: org.eclipse.persistence.platform.database.oracle.Oracle9Platform, regular expression: (?i)oracle.*9
FINEST: Database platform: org.eclipse.persistence.platform.database.oracle.OraclePlatform, regular expression: (?i)oracle.*
FINEST: Database platform: org.eclipse.persistence.platform.database.SQLAnywherePlatform, regular expression: SQL\ Anywhere.*
FINEST: Database platform: org.eclipse.persistence.platform.database.SybasePlatform, regular expression: (?i)(sybase.*)|(adaptive\ server\ enterprise.*)|(SQL\ Server.*)
FINEST: Database platform: org.eclipse.persistence.platform.database.SQLServerPlatform, regular expression: (?i)microsoft.*
FINE: Detected database platform: org.eclipse.persistence.platform.database.SQLServerPlatform
CONFIG: connecting(DatabaseLogin(
    platform=>DatabasePlatform
    user name=> ""
    connector=>JNDIConnector datasource name=>null
))
CONFIG: Connected: jdbc:jtds:sqlserver:
    User: user
    Database: Microsoft SQL Server  Version: 10.50.1600
    Driver: jTDS Type 4 JDBC Driver for MS SQL Server and Sybase  Version: 1.2.5
FINEST: Connection acquired from connection pool [read].
FINEST: Connection released to connection pool [read].
CONFIG: connecting(DatabaseLogin(
    platform=>SQLServerPlatform
    user name=> ""
    connector=>JNDIConnector datasource name=>null
))
CONFIG: Connected: jdbc:jtds:sqlserver:
    User: user
    Database: Microsoft SQL Server  Version: 10.50.1600
    Driver: jTDS Type 4 JDBC Driver for MS SQL Server and Sybase  Version: 1.2.5
FINEST: sequencing connected, state is Preallocation_Transaction_NoAccessor_State
FINEST: sequence child_uid: preallocation size 1
FINEST: sequence friend_uid: preallocation size 1
FINEST: sequence father_uid: preallocation size 1
FINEST: sequence mother_uid: preallocation size 1
INFO: file:/C:/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test login successful
WARNING: Multiple [2] JMX MBeanServer instances exist, we will use the server at index [0] : [com.sun.enterprise.v3.admin.DynamicInterceptor@266bad10].
FINER: JMX MBeanServer instance found: [com.sun.enterprise.v3.admin.DynamicInterceptor@266bad10], # of beans: [21], domain: [DefaultDomain] at index: [0].
WARNING: JMX MBeanServer in use: [com.sun.enterprise.v3.admin.DynamicInterceptor@266bad10] from index [0] 
FINER: JMX MBeanServer instance found: [com.sun.jmx.mbeanserver.JmxMBeanServer@6f7adf19], # of beans: [24], domain: [DefaultDomain] at index: [1].
WARNING: JMX MBeanServer in use: [com.sun.jmx.mbeanserver.JmxMBeanServer@6f7adf19] from index [1] 
FINEST: Registered MBean: org.eclipse.persistence.services.mbean.MBeanDevelopmentServices[TopLink:Name=Development-file_/C_/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test,Type=Configuration] on server com.sun.jmx.mbeanserver.JmxMBeanServer@6f7adf19
FINEST: Registered MBean: org.eclipse.persistence.services.glassfish.MBeanGlassfishRuntimeServices[TopLink:Name=Session(file_/C_/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test)] on server com.sun.jmx.mbeanserver.JmxMBeanServer@6f7adf19
FINEST: EclipseLink JMX Runtime Services is referencing the [Platform ConversionManager] ClassLoader at: [WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)]
FINEST: The applicationName for the MBean attached to session [file:/C:/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test] is [unknown]
FINEST: The moduleName for the MBean attached to session [file:/C:/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test] is [unknown]
FINER: Canonical Metamodel class [org.dima.model.Child_] not found during initialization.
FINER: Canonical Metamodel class [org.dima.model.Friend_] not found during initialization.
FINER: Canonical Metamodel class [org.dima.model.Father_] not found during initialization.
FINER: Canonical Metamodel class [org.dima.model.Mother_] not found during initialization.
FINEST: End deploying Persistence Unit test; session file:/C:/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test; state Deployed; factoryCount 1
FINER: client acquired: 50658177
FINER: TX binding to tx mgr, status=STATUS_ACTIVE
FINER: acquire unit of work: 1008456627
FINEST: Execute query ReadObjectQuery(name="readObject" referenceClass=Father sql="SELECT ID, NAME, SURNAME FROM LSDB.dbo.FATHER WHERE (ID = ?)")
FINEST: Connection acquired from connection pool [read].
FINEST: reconnecting to external connection pool
FINE: SELECT ID, NAME, SURNAME FROM LSDB.dbo.FATHER WHERE (ID = ?)
    bind => [3500]
FINEST: Connection released to connection pool [read].
INFO: mother isloaded=false
INFO: friendList isloaded=false
FINER: TX beforeCompletion callback, status=STATUS_ACTIVE
FINER: begin unit of work commit
FINER: TX afterCompletion callback, status=COMMITTED
FINER: end unit of work commit
FINER: release unit of work
FINER: client released
FINEST: Execute query ReadAllQuery(name="file:/C:/netbeans/projects/JPATestServer/build/web/WEB-INF/classes/_test" referenceClass=Friend )
FINEST: Connection acquired from connection pool [read].
FINEST: reconnecting to external connection pool
**FINE: SELECT ID, NAME, SURNAME, FATHERID FROM LSDB.dbo.FRIEND WHERE (FATHERID = ?)
    bind => [3500]**
FINEST: Connection released to connection pool [read].
FINEST: Register the existing object org.dima.model.Friend[ id=17496 ]
FINEST: Register the existing object org.dima.model.Friend[ id=17497 ]
FINEST: Register the existing object org.dima.model.Friend[ id=17498 ]
FINEST: Register the existing object org.dima.model.Friend[ id=17499 ]
FINEST: Register the existing object org.dima.model.Friend[ id=17500 ]

为什么JPA提供程序执行此操作 来自LSDB.dbo.FRIEND WHERE(FATHERID =?)的SELECT ID,NAME,SURNAME,FATHERID         bind =&gt; [3500]

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

默认情况下,只对Java SE环境中的xToMany关系进行延迟加载(因为EclipseLink可以使用使用集合的IndirectList)。如果你想延迟加载xToOne关系,你必须使用类编织。

答案 1 :(得分:2)

懒惰提取类型正在运行。延迟关系允许延迟引用实体的获取,直到它们首次被访问为止,这在您调用father.getFriendList()时似乎正在发生。如果它不起作用,这个调用什么都不做,并且当父亲被读入时立即获取关系。

EclipseLink允许访问延迟关系,只要连接仍然可用,如下所述:http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg05258.html如果序列化实体,您将获得异常,因为在关系中读取的上下文将不可用。

如果您希望在分离但未序列化的实体上访问延迟关系时抛出异常,请在EclipseLink中提交增强请求。

答案 2 :(得分:0)

  

EAGER 策略是持久性提供程序的要求   运行时必须急切地获取该值。 LAZY 策略是一个   提示到持久性提供程序运行时。

在这里找到这个答案。 JPA fetchType.Lazy is not working

还有一件事:JPA使用编织来实现这一目标。 wiki-eclipse