Hibernate: загрузка и LazyInitializationException - PullRequest
0 голосов
/ 31 декабря 2010

Согласно учебнику: http://jpa.ezhibernate.com/Javacode/learn.jsp?tutorial=27hibernateloadvshibernateget,

Если вы инициализируете экземпляр JavaBean с помощью вызова метода load, вы можете получить доступ к свойствам этого JavaBean только в первый раз в контексте транзакции, в котором он был инициализирован.

Если вы попытаетесь получить доступ к различным свойствам JavaBean после того, как транзакция, в которую он был загружен, была подтверждена, вы получите исключение LazyInitializationException, поскольку Hibernate больше не имеет действительного транзакционного контекста, который можно использовать для обращения к базе данных.

Но в моем эксперименте, использующем hibernate 3.6 и postgres 9, он вообще не выдает никаких исключений. Я что-то упустил?

Вот мой код:

import org.hibernate.Session;


public class AppLoadingEntities {
    /**
    * @param args
    */
    public static void main(String[] args) {
        HibernateUtil.beginTransaction();
        Session session = HibernateUtil.getSession();

        EntityUser userFromGet = get(session);
        EntityUser userFromLoad = load(session);

        // finish the transaction
        session.getTransaction().commit();

        // try fetching field value from entity bean that is fetched via get outside transaction, and it'll be okay
        System.out.println("userFromGet.getId() : " + userFromGet.getId());
        System.out.println("userFromGet.getName() : " + userFromGet.getName());

        // fetching field from entity bean that is fetched via load outside transaction, and it'll be errornous
        // NOTE : but after testing, load seems to be okay, what gives ? ask forums
        try {
            System.out.println("userFromLoad.getId() : " + userFromLoad.getId());
            System.out.println("userFromLoad.getName() : " + userFromLoad.getName());
        } catch(Exception e) {
            System.out.println("error while fetching entity that is fetched from load : " + e.getMessage());
        }
    }

    private static EntityUser load(Session session) {
        EntityUser user = (EntityUser) session.load(EntityUser.class, 1l);
        return user;
    }

    private static EntityUser get(Session session) {
        // safe to set it to 1, coz the table got recreated at every run of this app
        EntityUser user = (EntityUser) session.get(EntityUser.class, 1l);
        return user;
    }

}

А вот и вывод:

82 [main] INFO org.hibernate.annotations.common.Version - Hibernate Commons Annotations 3.2.0.Final
87 [main] INFO org.hibernate.cfg.Environment - Hibernate 3.6.0.Final
87 [main] INFO org.hibernate.cfg.Environment - hibernate.properties not found
90 [main] INFO org.hibernate.cfg.Environment - Bytecode provider name : javassist
92 [main] INFO org.hibernate.cfg.Environment - using JDK 1.4 java.sql.Timestamp handling
132 [main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml
132 [main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml
172 [main] WARN org.hibernate.util.DTDEntityResolver - recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
189 [main] INFO org.hibernate.cfg.Configuration - Configured SessionFactory: null
228 [main] INFO org.hibernate.cfg.AnnotationBinder - Binding entity from annotated class: EntityUser
254 [main] INFO org.hibernate.cfg.annotations.EntityBinder - Bind entity EntityUser on table MstUser
285 [main] INFO org.hibernate.cfg.Configuration - Hibernate Validator not found: ignoring
287 [main] INFO org.hibernate.cfg.search.HibernateSearchEventListenerRegister - Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
291 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!)
291 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 20
291 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false
300 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: org.postgresql.Driver at URL: jdbc:postgresql://localhost:5432/hibernate
300 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=sofco, password=****}
369 [main] INFO org.hibernate.cfg.SettingsFactory - Database ->
       name : PostgreSQL
    version : 9.0.1
      major : 9
      minor : 0
369 [main] INFO org.hibernate.cfg.SettingsFactory - Driver ->
       name : PostgreSQL Native Driver
    version : PostgreSQL 9.0 JDBC4 (build 801)
      major : 9
      minor : 0
386 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.PostgreSQLDialect
395 [main] INFO org.hibernate.engine.jdbc.JdbcSupportLoader - Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
396 [main] INFO org.hibernate.transaction.TransactionFactoryFactory - Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
397 [main] INFO org.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
397 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic flush during beforeCompletion(): disabled
397 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic session close at end of transaction: disabled
397 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch size: 15
397 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch updates for versioned data: disabled
397 [main] INFO org.hibernate.cfg.SettingsFactory - Scrollable result sets: enabled
397 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC3 getGeneratedKeys(): enabled
397 [main] INFO org.hibernate.cfg.SettingsFactory - Connection release mode: auto
398 [main] INFO org.hibernate.cfg.SettingsFactory - Default batch fetch size: 1
398 [main] INFO org.hibernate.cfg.SettingsFactory - Generate SQL with comments: disabled
398 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL updates by primary key: disabled
398 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL inserts for batching: disabled
398 [main] INFO org.hibernate.cfg.SettingsFactory - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
398 [main] INFO org.hibernate.hql.ast.ASTQueryTranslatorFactory - Using ASTQueryTranslatorFactory
399 [main] INFO org.hibernate.cfg.SettingsFactory - Query language substitutions: {}
399 [main] INFO org.hibernate.cfg.SettingsFactory - JPA-QL strict compliance: disabled
399 [main] INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled
399 [main] INFO org.hibernate.cfg.SettingsFactory - Query cache: disabled
399 [main] INFO org.hibernate.cfg.SettingsFactory - Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory
399 [main] INFO org.hibernate.cfg.SettingsFactory - Optimize cache for minimal puts: disabled
399 [main] INFO org.hibernate.cfg.SettingsFactory - Structured second-level cache entries: disabled
401 [main] INFO org.hibernate.cfg.SettingsFactory - Echoing all SQL to stdout
402 [main] INFO org.hibernate.cfg.SettingsFactory - Statistics: disabled
402 [main] INFO org.hibernate.cfg.SettingsFactory - Deleted entity synthetic identifier rollback: disabled
402 [main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo
402 [main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled
402 [main] INFO org.hibernate.cfg.SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled
424 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory
548 [main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
Hibernate: select entityuser0_.id as id0_0_, entityuser0_.name as name0_0_, entityuser0_.password as password0_0_ from MstUser entityuser0_ where entityuser0_.id=?
Hibernate: select entityuser0_.id as id0_0_, entityuser0_.name as name0_0_, entityuser0_.password as password0_0_ from MstUser entityuser0_ where entityuser0_.id=?
userFromGet.getId() : 1
userFromGet.getName() : Albert Kam xzy
userFromLoad.getId() : 1
userFromLoad.getName() : Albert Kam xzy

1 Ответ

2 голосов
/ 31 декабря 2010

Вы не видите это исключение, потому что в вашем load (...) методе у вас есть следующий System.out

System.out.println("user fetched with 'load' inside transaction : " + user);

И, как вы можете видеть, вы печатаете«пользователь», вызывая toString () на нем (это вызывается автоматически).И в журналах, которые я вижу, печатается следующее, что означает, что вы переопределили метод toString (), который внутренне вызывает метод getter каждого из заданных свойств.И поскольку все это происходит, когда транзакция еще открыта (вы совершаете транзакцию после вызова метода load (...)), вы не видите этого исключения.

user fetched with 'load' inside transaction : 1:Albert Kam xzy:abc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...