簡體   English   中英

@Transactional無法正常工作

[英]@Transactional isn't working

我有一個用@Service注釋的類,該類正在實現javax.jms.MessageListener,在onMessage函數內部,我從存儲庫中檢索一個對象,但是當我嘗試預加載延遲加載的屬性時,我得到“無法初始化代理-否會話”異常。

我寧願不要禁用延遲加載,因為頁面實體在很多子實體的幫助下變得非常大,而且在大多數情況下,我在使用頁面對象時不需要這些子實體。

我在Google上發現並嘗試了很多其他問題和解決方案,但似乎沒有一個對我有所幫助。

@Service
public class PageService implements MessageListener {
    private PageRepository pageRepository;
    public PageService(PageRepository pageRepository){
        this.pageRepository = pageRepository;
    }

    @Override
    @Transactional
    public void onMessage(Message message) {
        // Message handling etc etc..
        int id = ....
        Page page = pageRepository.findOne(id); // Page is retrieved successfully

        page.InitializeAll(); // <--- Error happens here

        // Build response message.
    }
}

實體:

@Entity
public class Page {
    ....

    @OrderBy("id ASC")
    @OneToMany(mappedBy = "page", cascade = CascadeType.ALL)
    public Set<Row> rows;

    public void InitializeAll(){
        Hibernate.initialize(this.rows);      // <--- Error
        rows.forEach(r -> r.InitializeAll());
    }
}

頁面存儲庫只是擴展了CrudRepository:

public interface PageRepository extends CrudRepository<Page, Integer>

在同一個包(/文件夾)中的另一個文件中,我有另一個函數,該函數帶有@Transactional注釋,內部具有相同的函數調用,在這里一切正常。

@MessageMapping("/page/{id}/request")
@SendToUser(value = "/queue/private", broadcast = false)
@Transactional
public initialPageMessage subscribeClient(@DestinationVariable("id") int pageId) {
    initialPageMessage resp = new initialPageMessage();
    resp.page = pageRepository.findOne(pageId);
    resp.page.InitializeAll();
    return resp;
 }

TransactionManagerConfiguration:

@Configuration
@EnableTransactionManagement
public class TransactionManagerConfiguration {
    private EntityManagerFactory entityManagerFactory;
    private DataSource datasource;

    public TransactionManagerConfiguration(EntityManagerFactory entityManagerFactory, DataSource datasource){
        this.entityManagerFactory = entityManagerFactory;
        this.datasource = datasource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(){
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(entityManagerFactory);
        tm.setDataSource(datasource);
        return tm;
    }
}

堆棧跟蹤

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: models.Page.rows, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:587) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:204) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:739) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.Hibernate.initialize(Hibernate.java:65) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at models.Page.InitializeAll(Page.java:31) ~[classes/:na]
    at controllers.PageService.processMessage(PageService.java:93) ~[classes/:na]
    at controllers.PageService.onMessage(PageService.java:75) ~[classes/:na]
    at org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1401) ~[activemq-client-5.14.3.jar:5.14.3]
    at org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131) [activemq-client-5.14.3.jar:5.14.3]
    at org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202) [activemq-client-5.14.3.jar:5.14.3]
    at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:133) [activemq-client-5.14.3.jar:5.14.3]
    at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48) [activemq-client-5.14.3.jar:5.14.3]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_40]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_40]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_40]

一段時間后,我發現了問題,問題是從同一類內部調用了“ onMessage”方法。 這樣可以防止@Transactional代理(包裝類)被調用。 當我將@Transactional移到另一個類並從該類外部調用該函數時,它開始工作。

暫無
暫無

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

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