49600

Why doesn't JPA's FetchType.LAZY work?

Question:

JPA provider eclipselink 2.3 AS glassfish 3.1.1 B12 Binary protocol for remote invocation Hessian

Server side ejb+jpa Client side Plain Swing .

<strong>JPA mappings</strong>

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

<strong>EJB Method</strong>

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

<strong>Client Side Call over Hessian</strong>

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

everything works fine, but when view server log and Father entity related parties I discovered that LazyLoaded anotated fields is filled from database.

<strong>Server Log</strong>

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 ]

Why JPA provider executes this <strong>SELECT ID, NAME, SURNAME, FATHERID FROM LSDB.dbo.FRIEND WHERE (FATHERID = ?) bind => [3500]</strong>

Any idea?

Answer1:

Lazy loading is only done for xToMany relation in a Java SE environment by default (since EclipseLink can use IndirectList where collections are used). If you want to lazy load xToOne relations you have to use class weaving.

Answer2:

Lazy fetch type is working. Lazy relationships allow delaying the fetching of the referenced entities until they are first accessed, which seems to be happenging when you call father.getFriendList(). If it were not working, this call would do nothing and the relationship fetched immediately when the father was read in.

EclipseLink allows accessing a lazy relationship as long as the connection is still available as described here: <a href="http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg05258.html" rel="nofollow">http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg05258.html</a> If you serialize the entity you will get the exception as the context to read in the relationship will not be available.

If you wish an exception be thrown instead when you access a lazy relationship on a detached but not serialized entity, please file an enhancement request in EclipseLink.

Answer3:

<blockquote>

The <strong>EAGER</strong> strategy is a <strong>requirement</strong> on the persistence provider runtime that the value must be eagerly fetched. The <strong>LAZY</strong> strategy is a <strong>hint</strong> to the persistence provider runtime.

</blockquote>

Found this answer here. <a href="https://stackoverflow.com/questions/18693849/jpa-fetchtype-lazy-is-not-working" rel="nofollow">JPA fetchType.Lazy is not working</a>

One more thing: JPA uses weaving to accomplish this. <a href="https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving" rel="nofollow">wiki-eclipse</a>

Recommend

  • Two simultaneous AJAX requests won't run in parallel
  • New line while writing to file in C?
  • Access of nested classes (which behave like friends, but aren't)
  • Inconsistent decimals in tick labels when using a log axis
  • Object reference not set to an instance of an object
  • Selecting sublevels of Multiindex columns in pandas
  • JSON array to ExpandoObject via JSON.NET
  • JUnit: how to access Spring configuration as Spring has intended?
  • knownhosts for Ant scp and sshexec tasks
  • Strange result of MPI_AllReduce for 16 byte real
  • react - how do I get the size of a component child elements and reposition them
  • json_encode dropping array_values key?
  • Hotkeys creation for java swing form
  • Working with search bar on iOS 9 [closed]
  • C Standard Library Functions vs. System Calls. Which is `open()`?
  • GC.start has no effect in Pry, but does in IRB
  • How to reset git pushed first commit into wrong new repo?
  • Why doesn't the tray icon context menu work for my RemoteApp?
  • How to add blur effect into UIImage with Swift? [duplicate]
  • How to organize this layout with overflows?
  • Why am I getting an Argument exception when creating event handler dynamically?
  • internal javascript not works in angular2
  • Google TV VideoView playing YouTube rtsp videos
  • cSPADE data mining in R using arulesSequences - Error while converting to “transactions” format
  • Haskell program that can handle any arbitrary deterministic finite automaton
  • .Net core Hosted Services guaranteed to complete
  • opencv deskewing a contour
  • How to define a custom accuracy in Keras to ignore samples with a particular gold label?
  • Using redis as an LRU cache for postgres
  • `$http:badreq Bad Request Configuration` - from angular post method, what is wrong here?
  • Jersey serializes character value to ASCII equivalent numeric string