2011-12-14 44 views
1

JPA提供商远程调用的Hessian为什么JPA的FetchType.LAZY不起作用?

服务器侧EJB + JPA 客户端侧平原摇摆的EclipseLink 2.3 AS的glassfish 3.1.1 B12 二进制协议。

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; 
    } 

客户端调用了黑森州

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) { 

    } 

} 

一切工作正常,但是当查看服务器日志和Father实体相关方时,我发现 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] : [[email protected]]. 
FINER: JMX MBeanServer instance found: [[email protected]], # of beans: [21], domain: [DefaultDomain] at index: [0]. 
WARNING: JMX MBeanServer in use: [[email protected]] from index [0] 
FINER: JMX MBeanServer instance found: [[email protected]], # of beans: [24], domain: [DefaultDomain] at index: [1]. 
WARNING: JMX MBeanServer in use: [[email protected]] 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 [email protected] 
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 [email protected] 
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提供商执行该 SELECT ID,名字,姓氏,FATHERID FROM LSDB.dbo.FRIEND WHERE(FATHERID =?) 绑定=> [3500]

有什么想法?

回答

2

懒惰获取类型正在工作。延迟关系允许延迟引用实体的读取,直到它们第一次被访问,这在您调用father.getFriendList()时似乎正在发生。如果它没有工作,这个调用将不会执行任何操作,当父亲被读入时,该关系立即被取回。

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

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

+1

是不是(触发)列表的toString()方法触发延迟加载的(隐式)调用? – 2011-12-14 15:17:01

+2

另外,我发现这种行为(事务提交后的延迟加载)可疑:如果事务具有READ_COMMITTED(或更严格)隔离级别,则在事务结束后延迟加载列表允许查看不存在的子项当事务运行时,并且不显示事务运行但已被删除的子项。你在ACID中失去了I和C. – 2011-12-14 15:21:24

5

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

0

EAGER策略是对持久性提供 运行时,该值必须预先抓取一个要求LAZY策略是 提示到持久性提供程序运行时。

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

还有一件事:JPA使用编织来完成此操作。wiki-eclipse

相关问题