[英]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.