Почему не работает JPA FetchType.LAZY? - PullRequest
1 голос
/ 14 декабря 2011

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 заполняются из базы данных.

Журнал сервера

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-провайдер выполняет это ВЫБЕРИТЕ ID, ИМЯ, ФАМИЛЮ, ОТЕЦ ОТ LSDB.dbo.FRIEND WHERE (FATHERID =?) bind => [3500]

Есть идеи?

Ответы [ 3 ]

5 голосов
/ 24 октября 2012

Ленивая загрузка по умолчанию выполняется только для отношения xToMany в среде Java SE (поскольку EclipseLink может использовать IndirectList там, где используются коллекции). Если вы хотите лениво загрузить отношения xToOne, вы должны использовать классное переплетение.

2 голосов
/ 14 декабря 2011

работает тип Lazy fetch.Ленивые отношения позволяют задерживать выборку объектов, на которые ссылаются, до тех пор, пока они не будут впервые доступны, что, кажется, происходит, когда вы вызываете Father.getFriendList ().Если бы это не сработало, этот вызов ничего бы не сделал, и связь была извлечена немедленно, когда отец был зачитан.

EclipseLink позволяет получить доступ к отложенным отношениям, пока соединение все еще доступно, как описано здесь:http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg05258.html Если вы сериализуете сущность, вы получите исключение, так как контекст для чтения во взаимосвязи будет недоступен.

Если вы хотите, чтобы вместо этого возникало исключение при доступе к отложенным отношениям на отдельном, но не сериализованном объекте, отправьте запрос на расширение в EclipseLink.

0 голосов
/ 21 сентября 2015

Стратегия EAGER является требованием для поставщика сохраняемости. время выполнения, что значение должно быть извлечено с нетерпением. Стратегия LAZY является подсказка к среде выполнения поставщика сохраняемости.

Нашел ответ здесь. JPA fetchType.Lazy не работает

Еще одна вещь: JPA использует ткачество для достижения этой цели. вики-затмение

...