2017-01-19 13 views
0

私はサービスクラスに@Transactionalというアノテートを付けて、DAOレイヤメソッドを呼び出して、遅れてコレクションがロードされたオブジェクトを返します。 Hibernate.inititialize(..)を使用してこのコレクションをサービスレイヤーで初期化しようとすると、hibernateはコレクションをロードしません。 DAOはエンティティマネージャを使用するように構成され、オブジェクトクラスにはJPAアノテーションが付いています。私は私のDAOインタフェースとimplementaionnは私のオブジェクトは次のようになりますコレクションの初期化が機能しないのはなぜですか?

package org.gmp.webapp.dao; 

import java.util.List; 
import org.gmp.webapp.model.Crime; 

public interface DAO { 
    public Crime getCrime(String crimeNo); 
} 

import org.gmp.webapp.dao.DAO; 
import org.gmp.webapp.model.Crime; 

public class HibDAOImpl implements DAO { 

    @PersistenceContext 
    protected EntityManager em; 

    public Crime getCrime(String crimeNo) { 
     return this.em.find(Crime.class, crimeNo); 
    } 

} 

...翌春のアプリケーションコンテキストを持っている...

<beans xmlns="http://www.springframework.org/schema/beans"..."> 

<orcl:pooling-datasource id="dataSource" url="..." username="..." password="..."/> 

<context:annotation-config/> 

<!-- Hibernate entity manager --> 
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="packagesToScan" value="org.gmp.webapp.model" /> 
    <property name="jpaVendorAdapter"> 
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
    </property> 
    <property name="jpaProperties"> 
    <props> 
     <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop> 
     <prop key="hibernate.hbm2ddl.auto">update</prop> 
     <prop key="hibernate.show_sql">true</prop> 
    </props> 
    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="myEmf" /> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="persistenceExceptionTranslationPostProcessor" 
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 

<bean id="dao" class="org.gmp.webapp.dao.impl.HibDAOImpl" /> 
</beans> 

..

@Entity 
@Table(name="CRIME_TABLE") 
public class Crime { 
    @Id 
    @Column(name = "CRIME_NO") 
    private String crimeNo; 
    @OneToMany 
    @JoinColumn(name="PER_CRIME_NO", referencedColumnName="CRIME_NO") 
    private List<PersonCrimeLink> personLinks; 
    .... 
    public List<PersonCrimeLink> getPersonLinks() { 
     return personLinks; 
    } 
} 

サービスクラスがされ私はDAOと初期化の呼び出しが同じトランザクション内にあったので、トランザクション型(春)のアノテーションが付いているので、これはうまくいくはずです。 マイサービス..

@Service 
@Transactional(readOnly=true) 
public class CrimeServiceImpl implements CrimeService { 

    @Autowired private CrimeDAO crimeDAO; 

    public Crime getCrime(String crimeNo) { 
     Crime crime = crimeDAO.getCrime(crimeNo); 
     Hibernate.initialize(crime.getPersonLinks()); 
     return crime; 
    } 
} 

私はDAOメソッドのテストを実行したときに、コレクションがロードされ、コレクションのためのゲッターへの呼び出しを行うとき。私は@Transactionalでテストメソッドに注釈を付けました。 personLinksオブジェクトは省略されていますが、私が言うように、テストのレコードを返します。私は、セッション・ファクトリとHibernateTransactionManagerを使用していたときにこのプロセスが機能するので、私が使用しているトランザクション・マネージャを理解していないと思います。 多くの方にはこれに関するガイダンスをお寄せいただきありがとうございます。

答えて

1

あなたのorm APIとしてHibernateのSessionFactoryではなくJPAのEntityManagerFactoryを使用することを決めたので、私はアプリケーションの他のレイヤーでそのAPIに固執します。

つまり、EntityManagerを使用してデータを取得し、実装API(Hibernate.initialize)を使用して切り替えることは、一貫した/維持可能なアプローチではありません。

あなたはそれが初めてアクセスされると、コレクションを初期化しているJPA仕様、に固執するならば、あなたはすべてのエラーを取得しないと、リストがロードされ、ポストに言ったように:

:LAZY戦略は、それが最初

にアクセスしたときに データを遅延フェッチするので、JPA仕様のように、あなただけのこの操作を行う必要がある持続性プロバイダのランタイムへのヒントです

+0

こんにちは、ありがとうございます。だから私はコレクションを初期化して同じオブジェクトを取得する別のメソッドが必要になります。 Hibernate.initializeに代わる方法はありません。そこにあるべきであるように思われる。 – user2554194

+0

いいえ、コレクションにアクセスする必要があるのは、依然としてトランザクションコンテキストの下にある間は何らかの方法です。最新の投稿をご覧ください。 –

+0

これは私にとっては役に立ちません。そのようなトランザクションのようなサービスで開始されていない、。私の設定が正しくないかもしれません。 – user2554194

関連する問題