Java Hibernate:加载和LazyInitializationException

Java Hibernate:加载和LazyInitializationException,java,hibernate,Java,Hibernate,根据教程: 如果使用load方法调用初始化JavaBean实例,则只能在初始化JavaBean的事务上下文中首次访问该JavaBean的属性 如果在提交加载JavaBean的事务之后尝试访问JavaBean的各种属性,您将得到一个异常,一个LazyInitializationException,因为Hibernate不再具有用于访问数据库的有效事务上下文 但在我的实验中,使用Hibernate3.6和Postgres9,它根本不会引发任何异常。我错过什么了吗 这是我的密码: import org

根据教程:

如果使用load方法调用初始化JavaBean实例,则只能在初始化JavaBean的事务上下文中首次访问该JavaBean的属性

如果在提交加载JavaBean的事务之后尝试访问JavaBean的各种属性,您将得到一个异常,一个LazyInitializationException,因为Hibernate不再具有用于访问数据库的有效事务上下文

但在我的实验中,使用Hibernate3.6和Postgres9,它根本不会引发任何异常。我错过什么了吗

这是我的密码:

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

您没有看到该异常,因为在load(…)方法中有下面的System.out

System.out.println("user fetched with 'load' inside transaction : " + user);
如您所见,您通过调用toString()来打印“user”(这是自动调用的)。在日志中,我看到下面的内容正在打印,这意味着您已经重写了toString()方法,该方法在内部调用每个给定属性的getter方法。由于这一切都是在事务仍处于打开状态时发生的(您在调用load(…)方法后提交事务),因此您没有看到此异常

user fetched with 'load' inside transaction : 1:Albert Kam xzy:abc

你好我在写了这篇文章之后也意识到了这一点,我正在编辑我原来的文章。但是,我还是试着对System.out.println进行注释,它仍然有效,没有任何例外。我编辑了我的原始帖子,删除了System.out.println部分,还更新了日志输出。谢谢。您是否也可以评论“EntityUser userFromGet=get(会话)”并查看。我认为这是可行的,因为您试图在同一事务中查询同一实体(id==1L),而由于事务缓存,同一对象正在返回。既然你第一次得到了(…),实体已经被填充了。啊,我明白了。。。这就是问题所在。非常感谢你!我想我现在不会因为任何原因使用load。这种行为很难调试。