Почему я не могу сделать этот бин @Transactional весной? - PullRequest
5 голосов
/ 20 июня 2011

Я пишу простой bean-компонент, который хочу настроить с именем таблицы, XML-файлом с некоторыми данными, чтобы при запуске приложения таблица была пуста, и она инициализировалась с этими данными. Я решил использовать простые запросы SQL, но не могу получить сеанс из фабрики сеансов, потому что там написано:

Error creating bean with name 'vecchiOrdiniFiller' defined in ServletContext resource [/WEB-INF/spring/servlet-context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

Но это конфигурация (очень похожая на услугу):

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory" />
</bean>

<tx:annotation-driven />

<bean id="ordiniVecchioSistemaLoader" class="it.jsoftware.jacciseweb.assistenza.common.ExcelXmlDataLoader">
    <property name="xmlFileName" value="WEB-INF/data/daticlientijaccisemarco.xml"></property>
</bean>

<bean id="vecchiOrdiniFiller" class="it.jsoftware.jacciseweb.assistenza.common.BaseTableFiller" init-method="init">
    <property name = "sessionFactory" ref = "mySessionFactory"></property>
    <property name="loader" ref="ordiniVecchioSistemaLoader"></property>    
    <property name="tableCreationString" value="CREATE TABLE `vecchiordini` (  `ID` INT(11) NOT NULL AUTO_INCREMENT,  `codicejazz` VARCHAR(255) DEFAULT NULL,  `progressivolicenza` INT(11),  `codicearticolo` VARCHAR(255) DEFAULT NULL,  `rivenditore` VARCHAR(255) DEFAULT NULL,  `cliente` VARCHAR(255) DEFAULT NULL,  PRIMARY KEY (`ID`)) ENGINE=INNODB DEFAULT CHARSET=utf8"></property>
    <property name="table" value="vecchiordini"></property>
    <property name="tableColumns">
        <list>
            <value>codicejazz</value>
            <value>progressivolicenza</value>
            <value>codicearticolo</value>
            <value>rivenditore</value>
            <value>nomecliente</value>
        </list>
    </property>
    <property name="loaderColumns">
        <list>
            <value>clicod</value>
            <value>licsmatricola</value>
            <value>artcod</value>
            <value>rivenditore</value>
            <value>cliente</value>
        </list>
    </property>
</bean>

и я аннотировал метод init () с помощью @Transactional. Но транзакция не запускается, и я получаю эту ошибку:

@Transactional
public void init() throws Exception {
    logger.info("BaseTableFilter per tabella: " + table + ", usando: "
    + loader.getSourceName());

    Session session = dao.getSession();
    Transaction tx = session.beginTransaction();
    ...

почему это не работает?

Ответы [ 2 ]

15 голосов
/ 20 июня 2011

Аннотированные методы init-method или @PostConstruct не проксируются, поэтому вы не сможете использовать @Transactional для этого.Вы должны использовать @Transactional на вашем сервисе, почему он вам не подходит?Цитируется из SpringSource Jira :

На самом деле это определено так: методы init (такие как методы @PostConstruct) всегда вызываются на самом целевом экземпляре.Прокси-сервер будет сгенерирован только после полной инициализации целевого экземпляра ... Другими словами, прокси-сервер @Transactional даже не создается в точке вызова @PostConstruct.

Переключение в режим =«aspectj» помог бы, так как он напрямую переплетает целевой класс, и в этом случае метод init будет изменен для обеспечения транзакционной осведомленности уже во время вызова контейнера init.

Я думаю, что как минимум, мыследует более четко задокументировать ограничения @Transactional для прокси-серверов и указать, где mode = "aspectj" может быть решением.

Как уже говорилось, вы можете попробовать mode="aspectj", а лучше пересмотретьВаш дизайн на мой взгляд.

2 голосов
/ 20 июня 2011

Не думаю, что вы можете сделать метод init транзакционным.Но вы можете вызвать из него другой транзакционный метод другой службы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...