2011-12-14 2 views
1

JPAプロバイダリモート呼び出しヘッセ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) { 

    } 

} 

すべて正常に動作しますが、ビューサーバーのログや父親のエンティティ関連のパーティーでは、 がLazyLoadedアノテーション付きフィールドがデータベースから埋め込まれていることがわかりました。

サーバーログJPAプロバイダは(FATHERID =?) バインド=> [3500] LSDB.dbo.FRIEND FROMこの SELECT ID、NAME、SURNAME、FATHERIDを実行なぜ

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 ] 

答えて

2

遅延フェッチタイプが機能しています。遅延関係は、参照されるエンティティの最初のアクセスまで遅延させることができます。これは、father.getFriendList()を呼び出すとうまくいくようです。それが機能していなかった場合、この呼び出しは何もせず、父が読み込まれた直後に関係が取得されます。

EclipseLinkでは、接続がまだ利用可能である限り、遅延接続にアクセスできます。http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg05258.htmlエンティティでは、関係で読み込むコンテキストが利用できないため、例外が発生します。

デタッチされているがシリアル化されていないエンティティで遅延関係にアクセスするときに例外をスローする場合は、EclipseLinkで拡張要求を提出してください。

+1

遅延読み込みをトリガするリストのtoString()メソッドへの(暗黙の)呼び出しではありませんか? –

+2

また、(トランザクションがコミットした後のレイジーローディングの)この動作は疑わしいです:トランザクションにREAD_COMMITTED(またはより厳しい)分離レベルがある場合、トランザクションが終了した後にリストをレイジーロードすると、トランザクションが実行されたときに存在し、その後に削除された子を表示しません。あなたはACIDのIとCを失う。 –

+0

遅延ロードはうまく動作しますが、Fatherエンティティ・サーバーへの最初のアクセス時に、Father's Friendsのsql selectが実行されます。子エントリのSQL実行を停止する方法 "SELECT ID、NAME、SURNAME、FATHERID FROM LSDB.dbo.FRIEND WHERE(FATHERID =?)bind => [3500]" – dimitri

5

デフォルトでは、Java SE環境では、xToMany関係の遅延読み込みが実行されます(EclipseLinkは、コレクションが使用されるIndirectListを使用できるため)。 xToOneリレーションを読み込みたい場合は、クラスウィービングを使用する必要があります。

+0

あなたは研究室の王です。わたしは、あなたを愛しています。 – Alex

0

EAGER戦略値が熱心にフェッチされなければならない永続プロバイダ ランタイムに要件あります。 LAZY戦略は、持続性プロバイダランタイムへのヒント ヒントです。

ここでこの回答が見つかりました。 JPA fetchType.Lazy is not working

もう1つ:JPAはこれを達成するために織りを使用します。wiki-eclipse

関連する問題