2016-05-19 5 views
0

私は単純なコードを持っています。私は最初のプレーヤーにニックを設定したいここにデータベースにいくつかの選手を追加し、:Hibernate - LazyInitializationException

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); 
} 

ここにもう1つ質問があります:@TransactionalはDAO層またはサービス層になければなりませんか?

休止状態設定:

// 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; 
    } 
} 
+0

例えばアクティブなセッションに

プレイヤーエンティティがデタッチ状態にあり、管理されていないあなたがプレーヤーをマージする必要がある。この問題は、重複をたくさん持っています。そのうちの1つはhttp://stackoverflow.com/questions/19047835/hibernate-lazyinitializationexception-while-using-collection-in-spring-jsp-page –

答えて

0

休止中loadメソッドは、プロキシではなく実際のオブジェクトを返すことがあります。 Hibernateセッションがまだ開かれている間に、永続プロパティの1つがアクセスされると、プロキシはエンティティ状態をロードします。

あなたのケースでは、Hibernateセッションは@Transactionalの存在により作成されたトランザクションにバインドされています。トランザクションが完了すると、プロキシがロードされる前にセッションが閉じられます。エンティティの状態を常に取得するgetメソッドを使用するように、次のメソッドを変更します。 NBは、メソッドを取得して、キー

変更

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

NB

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

へのあなたのMOD()メソッドが更新されて t result in the playerのニックネームを獲得するために何行がデータベースに見つからない場合はnullを返しますデータベースに格納されます。変更を監視してデータベースにフラッシュするためにアクティブなセッションはありません。

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

Then in PlayerService 

@Transactional 
public void updatePlayer(Player player){ 
    session.merge(player); 
} 
+0

例外ではありませんが、ニックネームは変更されません – Bambelal

+0

ニックネームは変更されません変更を監視し、データベースにフラッシュするためのアクティブなセッションがないうちに、私は –

+0

を反映するように答えを更新しています。しかし、コントローラからmod()を削除してサービスレイヤに置くと、 ? – Bambelal

関連する問題