3

MyDao クラスには、Hibernate SessionFactory を介して永続化タスク全体を実行するメソッドがあり、正常に動作します。

上記のように MyService に MyDao を注入しますが、注入された MyDao の後に @PostConstruct init() メソッドが呼び出されると (デバッグすると、MyDao が十分に注入されていることがわかります)、次の Hibernate 例外が発生します。

org.hibernate.HibernateException: 現在のスレッドのセッションが見つかりません

私のサービスの実装。

@Service("myService")
@Transactional(readOnly = true)
public class MyServiceImpl implements MyService {

    @Autowired
    private MyDao myDao;
    private CacheList cacheList;

    @PostConstruct
    public void init() {

        this.cacheList = new CacheList();
        this.cacheList.reloadCache(this.myDao.getAllFromServer());
    }

    ...
}

解決方法

@ Yogiが上記で推奨したように、TransactionTemplateを使用して有効/アクティブなトランザクションセッションを1つ取得しました。この場合、コンストラクターを実装して正常に動作します。

@Service("myService")
@Transactional(readOnly = true)
public class MyServiceImpl implements MyService {

    @Autowired
    private MyDao myDao;
    private CacheList cacheList;

    @Autowired
    public void MyServiceImpl(PlatformTransactionManager transactionManager) {

        this.cacheList = (CacheList) new TransactionTemplate(transactionManager).execute(new TransactionCallback(){

            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {

                CacheList cacheList = new CacheList();
                cacheList.reloadCache(MyServiceImpl.this.myDao.getAllFromServer());

                return cacheList;
            }

        });
    }

    ...
}
4

3 に答える 3

5

@PostConstructレベルで許可されているトランザクションはないと思うので、 がin に設定されて@Transactionalいない限り、ここではあまり機能しません。modeaspectj<tx:annotation-driven mode="aspectj" />

この議論に従って、バインドするTransactionTemplate内部で手動トランザクションを開始するために使用できますが、宣言型トランザクションに厳密に従う場合は、トランザクションを開始するためにイベントとユーザーを登録するために使用する必要があります。init()sessionApplicationListenerContextRefreshedEvent

于 2014-03-05T09:56:17.377 に答える