为什么我不能在Spring中创建这个bean @Transactional?

got*_*ch4 5 sql spring transactions

我正在编写一个我想用表名配置的简单bean,一个包含一些数据的XML文件,这样如果在应用程序启动时表是空的,那么就会使用该数据进行初始化.我决定使用简单的SQL查询,但我无法从sessionfactory获取会话,因为它说:

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>
Run Code Online (Sandbox Code Playgroud)

我用@Transactional注释了init()方法.但它没有启动事务,我得到了这个错误:

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

    Session session = dao.getSession();
    Transaction tx = session.beginTransaction();
    ...
Run Code Online (Sandbox Code Playgroud)

为什么不工作?

aba*_*ogh 15

init-method@PostConstruct注解的方法没有代理,所以你将无法使用@Transactional上.您应该在服务上使用@Transactional,为什么不适合您?引自SpringSource Jira:

实际上,这是定义的:始终在目标实例本身上调用init方法(例如@PostConstruct方法).只有在目标实例完全初始化后才会生成代理...换句话说,甚至还没有在@PostConstruct调用点创建@Transactional代理.

切换到mode ="aspectj"会有所帮助,因为它直接编织目标类,在这种情况下,init方法已经在容器初始化调用时被修改为事务感知.

我想至少,我们应该更清楚地记录@Transactional对代理的限制 - 并指出mode ="aspectj"可能是一个解决方案.

如上所述,你可以尝试,mode="aspectj"但你应该在我看来审查你的设计.