我使用Spring 3.2.9將多層架構設計分解爲3個模塊web,service,repository。在倉庫中,我定義了一個通用的DAO類,我通過其他實體特定的DAO類繼承。LazyInitializationException和@Transactional不起作用
問題是,當我嘗試懶惰地從服務層獲取我的實體集合時,我總是得到LazyInitializationException。我曾嘗試將@Transactional放在我的服務類上,但它似乎不起作用。我只能避免異常,如果我立即在DAO類方法中初始化所有惰性集合(並且僅在我使用@Transactional註釋DAO類時),但我只想在商業邏輯中需要它們時才獲取這些集合,而不是所有集合提前。
奇怪的是@Transactional只能在DAO層中工作,而不能在服務層中使用。我發現了一些解決此問題的方法,但我有興趣真正取消解決並解決此問題,而不僅僅是使代碼工作。
儲存庫模塊:
@Repository
public abstract class GenericDao<T> {
protected Class<T> entityClass;
@PersistenceContext
protected EntityManager entityManager;
.........
public T findById(long id) {
T entity = entityManager.find(entityClass, id);
if (entity == null) {
throw new EntityNotFoundException(entityClass.getSimpleName(), id);
}
return entity;
}
}
我的服務模塊服務類:
@Service
public class UserServiceImpl implements UserService {
private UserDao userDao;
@SuppressWarnings("SpringJavaAutowiringInspection")
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Transactional(readOnly = true)
@Override
public UserDto getUserById(long id) {
User user = userDao.findById(id);
return new UserDto(user);
}
的DTO構造函數試圖訪問user.getTeams(),然後發生異常。取而代之的是,集合應該通過對數據庫的額外查詢來獲取。
配置:
庫配置: ......一些其他配置一樣的數據源...
<!--EntityManagerFactory-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.dialect" value="${hibernate_dialect}"/>
<entry key="hibernate.hbm2ddl.auto" value="${hibernate_Hbm2ddlAuto}"/>
<entry key="hibernate.show_sql" value="${hibernate_showSql}"/>
<entry key="hibernate.format_sql" value="${hibernate_formatSql}"/>
</map>
</property>
</bean>
的persistence.xml:
<persistence-unit name="persistenceUnit">
...other classes..
<class>com.example.entity.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
服務配置:
<import resource="classpath*:META-INF/repositoryApplicationContext.xml"/>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
檢查配置。請參閱:https://stackoverflow.com/questions/10538345/spring-transactional-annotations-ignored –
@AlanHay謝謝你,我找到了答案有 – zozo