【问题标题】:@Transactional questions and how to use with @Service@Transactional 问题以及如何与 @Service 一起使用
【发布时间】:2012-04-01 18:57:10
【问题描述】:

我的服务使用了一个通用的 DAO(它明确地使用了 Hibernate 会话工厂)。我花了一些时间才发现这个错误

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

我为我的服务添加了注释,一切正常。现在我想使用上下文路径扫描,并从我的配置中删除这一行:

<bean id="societaService" class="it.trew.prove.services.SocietaService" />

所以....这是我的最终版本:

@Service
@Transactional(readOnly = true)
public class SocietaService {

    private Dao societaDao;

    @Autowired
    public void setSocietaDao(Dao societaDao) {
        this.societaDao = societaDao;
    }

    public void salvaSocieta(Societa s) {
        societaDao.save(s);
    }

    public List<Societa> listAll() {
        return societaDao.getAll(Societa.class);
    }

    public void deleteById(Long id) {
        societaDao.delete(getSocieta(id));
    }

    public Societa getSocieta(String id) {
        return getSocieta(Long.parseLong(id));
    }

    public Societa getSocieta(Long id) {
        return societaDao.get(Societa.class, id);
    }
}

添加@Service 注释会使我的应用程序出现上述可怕的休眠错误。为什么? 删除 @Service 并通过 xml 配置服务 bean = 它可以工作。为什么??

另外:

  • 事务性注释我的服务类是否使其所有方法都在事务中执行?

编辑

这是我的上下文 xml:

<context:annotation-config />   
<context:component-scan base-package="it.trew.prove" /> 

<!--  Hibernate -->

<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.google.appengine.api.rdbms.AppEngineDriver" />
<property name="url" value="jdbc:google:rdbms://xxx:xxx/xxx" />
</bean>


<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="myDataSource" />
    <property name="annotatedClasses">
        <list>
            <value>it.trew.prove.model.beans.Scadenza</value>
            <value>it.trew.prove.model.beans.Fornitore</value>
            <value>it.trew.prove.model.beans.Societa</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
            <!-- <prop key="hibernate.hbm2ddl.import_files">/setup.sql</prop> -->
        </props>
    </property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

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

【问题讨论】:

  • 显示更多的 xml 配置
  • 我知道这里不是这种情况,但是如果你有删除或保存之类的操作,你不能设置readOnly=true。您应该为每种方法放置一个带有适当设置的@Transactional
  • 您的应用程序中的哪个位置(什么操作)导致异常以及您的Dao 是什么样的?
  • @pap 好像当我添加服务注释时......事务注释停止工作。

标签: java spring hibernate service transactions


【解决方案1】:

你启用注释了吗?

<context:annotation-config />

<context:component-scan base-package="org.example"/>

这将启用@Service、@Component 和@Repository 等注释

【讨论】:

  • 我没有你写的第一行。但是,结果并没有改变。
【解决方案2】:

首先,你需要告诉 spring 启用 Transactional annotation,如下所示:

<tx:annotation-driven transaction-manager="transactionManager" />

其次,如果您在类级别使用@Transactional,则对您的服务方法的任何调用都将是事务性的。是否启动事务取决于“传播”属性。如果在此会话中没有启动(Propagation.REQUIRED),则默认为启动一个。如果你只在类级别使用@Transactional,你所有的方法都将继承它的属性,即如果你设置“readOnly = true”,你所有的方法都将是只读的,因此,更新/保存/删除将不起作用.我建议您阅读更多Spring Transaction Management Doc

【讨论】:

  • 我已经有了那行,正如您在编辑中看到的那样。不过感谢您的信息。我会读
猜你喜欢
  • 2013-09-01
  • 1970-01-01
  • 2020-07-23
  • 2012-05-10
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多