Hibernate - LazyInitializationException

时间:2016-05-19 15:55:55

标签: java spring hibernate

我有一个简单的代码。我在数据库中添加了一些玩家,在这里我想在第一个玩家中设置缺口:

private void mod() {
    Player p = playersService.loadById(1L);
    p.setNick("OtherNick");
}

它给出:org.hibernate.LazyInitializationException: could not initialize proxy - no Session

PlayersService.load():

@Transactional
public Player loadById(Long id) {
    return playersDao.load(id);
}

PlayersDao.load() - 从AbstractDao延伸:

@SuppressWarnings("unchecked")
public T load(Serializable id) {
    return (T) currentSession().load(getDomainClass(), id);
}

我还有一个问题:@Transactional应该在DAO层还是服务层?

Hibernate配置:

// package declaration and import statements

@Configuration
@ComponentScan(basePackages = { "eniupage" }, excludeFilters = {
        @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
@EnableTransactionManagement
public class RootConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName( "com.mysql.jdbc.Driver" );
        dataSource.setUrl( "jdbc:mysql://localhost:3306/eniupage" );
        dataSource.setUsername( "eniupage" );
        dataSource.setPassword( "qwer1234" );
        return dataSource;
    }

    @Autowired
    @Bean
    public LocalSessionFactoryBean sessionFactory( DataSource dataSource ) {
        LocalSessionFactoryBean sfb = new LocalSessionFactoryBean();
        sfb.setDataSource( dataSource );
        sfb.setPackagesToScan( new String[] { "eniupage.domain"} );
        Properties props = new Properties();
        props.setProperty( "hibernate.dialect", "org.hibernate.dialect.MySQLDialect" );
        props.setProperty( "hibernate.hbm2ddl.auto", "create-drop" );
        props.setProperty( "hibernate.show_sql", "true" );

        sfb.setHibernateProperties( props );
        return sfb;
    }



    @Bean
    public BeanPostProcessor persistenceTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Autowired
    @Bean(name = "transactionManager")
    public HibernateTransactionManager getTransactionManager(
            SessionFactory sessionFactory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager(
                sessionFactory);

        return transactionManager;
    }
}

1 个答案:

答案 0 :(得分:0)

Hibernate中的load方法可能会返回代理而不是真实对象。然后,当Hibernate会话仍然打开时,代理将在访问其中一个持久属性时加载实体状态。

在您的情况下,Hibernate会话绑定到由于@Transactional的存在而创建的事务。事务完成后,会话在代理加载之前关闭。更改以下方法以使用始终获取实体状态的get方法。如果在提供的密钥

的数据库中找不到行,则N.B get方法返回null

改变
HelloWorld Project -> Targets -> General -> Embedded Binaries

return (T) currentSession().load(getDomainClass(), id);

N.B你的mod()方法赢得了return (T) currentSession().get(getDomainClass(), id); 在数据库中更新的昵称。没有活动的会话来监视更改并刷新数据库。玩家实体处于分离状态且未被管理您需要将玩家合并到活动会话

例如

t result in the player