私は、多層アーキテクチャ設計でSpring 3.2.9を使用しており、Web、サービス、リポジトリの3つのモジュールに分かれています。リポジトリでは、私は他のエンティティ固有のDAOクラスを継承するジェネリックDAOクラスを定義しました。LazyInitializationExceptionと@Transactionalが動作しない
問題は、サービスレイヤから自分のエンティティのコレクションを取得しようとすると、常にLazyInitializationExceptionが発生することです。私はサービスクラスに@Transactionalを置こうとしましたが、うまくいかないようです。 DAOクラスのメソッドですぐにすべての遅延コレクションを初期化して(@TransactionalでDAOクラスに注釈を付ける場合のみ)例外を避けることができますが、それらはすべてbussinessロジックで必要とされるときにのみ取得したいあらかじめ。
@TransactionalはDAOレイヤーでのみ動作しますが、使用すべきサービスレイヤーでは動作しないというのは奇妙なことです。私はこの問題を回避する方法をいくつか見つけましたが、私は本当にこの問題を軽視し解決することに興味があり、コードを作るだけではありません。
リポジトリMODULE:
@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を(アクセスしようとする)と、例外が発生します。その代わりに、DBへの追加のクエリを使用してコレクションを取得する必要があります。
構成:
リポジトリの構成: ......データソースのようないくつかの他の構成...
<!--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