@Transactional问题以及如何使用@Service

时间:2012-03-16 08:01:37

标签: java spring hibernate service transactions

我的服务使用通用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注释使我的应用程序在上面给出了可怕的hibernate错误。为什么? 删除@Service并通过xml =配置服务bean可以正常工作。 WHY ??

另外:

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

修改

这是我的上下文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> 

2 个答案:

答案 0 :(得分:3)

您是否启用了注释?

<context:annotation-config />

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

这将启用@ Service,@ Component和@Repository

等注释

答案 1 :(得分:1)

首先,您需要告诉spring以使用类似的方式启用Transactional注释:

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

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