2010-12-31 6 views
0

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

Если инициализировать JavaBean экземпляра с помощью вызова метода загрузки, вы можете получить доступ только свойства этого 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 

ответ

2

Вы не видите, что исключение, потому что в вашей нагрузки (...) метод вы имеете ниже системы .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 
+0

Hello. Я понял об этом и после создания этого сообщения, и я уже редактировал свой оригинальный пост. Но все же я пробовал комментировать System.out.println, и он по-прежнему работает без каких-либо исключений. Я редактировал свое оригинальное сообщение, удаляя разделы System.out.println, а также обновляя выход журнала. Спасибо. – bertie

+0

можете также прокомментировать «EntityUser userFromGet = get (session)» и посмотреть. Я думаю, что это работает, так как вы пытаетесь запросить одну и ту же сущность (id == 1L) в той же транзакции, когда тот же объект возвращается из-за транзакционного кэширования. И так как вы сначала получили (...) объект уже заселен. –

+0

Ahhh, я смотри ... Это была проблема. Большое спасибо ! Я не думаю, что теперь буду использовать нагрузку по любой причине. Поведение довольно сложно отладить. – bertie

Смежные вопросы