簡體   English   中英

為什么我的收藏初始化無效?

[英]Why is my initialisation of collection not working?

我有一個用@Transactional注釋的服務類,該服務類調用DAO層方法以返回帶有延遲加載的對象的對象。 然后,當我嘗試使用Hibernate.inititialize(..)在服務層中初始化此集合時,hibernate不會加載該集合。 DAO配置為使用實體管理器,並且用JPA注釋對對象類進行注釋。 我有以下Spring應用程序上下文。

<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>

我的DAO界面和實現...

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

}

我的對象看起來像這樣。

@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方法進行測試時,調用集合的getter時,將加載集合。 我已經用@Transactional注釋了測試方法。 personLinks對象被省略,但是就像我說的那樣,它返回測試中的記錄。 我認為我不了解我正在使用的事務管理器,因為當我使用會話工廠和HibernateTransactionManager時,此過程有效。 非常感謝您對此的任何指導。

這只是一個快速提示,因為您決定使用JPA的EntityManagerFactory而不是Hibernate的SessionFactory作為orm API,所以我會在應用程序的其他層上堅持使用該API。

也就是說,使用EntityManager獲取數據然后切換到使用實現API(Hibernate.initialize)並不是一種一致/可維護的方法。

就像您在帖子中所說的那樣,如果您遵循JPA規范,該規范將在首次訪問集合時對其進行初始化,那么您將不會收到任何錯誤,並且會加載列表:

LAZY策略向持久性提供程序運行時提供了一個提示,即在首次訪問數據時應延遲獲取數據

因此,從JPA規范開始,您只需要執行以下操作:

public Crime getCrime(String crimeNo) {
        Crime crime = crimeDAO.getCrime(crimeNo);
        crime.getPersonLinks().size(); // any access method
        return crime;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM