@Transactional + spring + hibernate不起作用

时间:2012-07-03 07:02:12

标签: spring hibernate transactional

我的背景:

`<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    <context:annotation-config />
    <context:component-scan base-package="com.globerry.project.domain" />
    <context:component-scan base-package="com.globerry.project.dao" /> 
    <context:component-scan base-package="com.globerry.project.service" />


        <!-- Файл с настройками ресурсов для работы с данными (Data Access Resources) -->
        <tx:annotation-driven transaction-manager="transactionManager" /> 
    <!-- Менеджер транзакций -->


    <!-- Настройки бина dataSource будем хранить в отдельном файле -->
  <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="classpath:/META-INF/jdbc.properties" />

    <!-- Непосредственно бин dataSource -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="com.mysql.jdbc.Driver" 
        p:url="${jdbc.databaseurl}"
        p:username="${jdbc.username}" 
        p:password="${jdbc.password}" />

    <!-- Настройки фабрики сессий Хибернейта -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
        p:packagesToScan="com.globerry.project.Dao">

        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop> 
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.connection.charSet">UTF-8</prop>
            </props>
        </property>
    </bean>

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

----------

我的DaoClass

`
@Repository
public class CityDao implements ICityDao {

    @Autowired
    SessionFactory sessionFactory;
@Override
    @Transactional(readOnly=true)
    public City getCityById(int id) {
        City city = (City) sessionFactory.getCurrentSession().get(City.class, id);
        Hibernate.initialize(city.getEvents());
        return city;
    }
}
`

----------

我对“道道法”有疑问。

getCityById(int id).

Hibernate抛出异常

org.hibernate.HibernateException: get is not valid without active transaction
        at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:341)
        at $Proxy36.createQuery(Unknown Source)
        at com.globerry.project.dao.CityDao.getCityById(CityDao.java:290)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy34.getCityById(Unknown Source)
        at com.globerry.project.dao.CityDaoTest.LazyTest(CityDaoTest.java:274)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)

com.globerry.project.dao.CityDaoTest.LazyTest()标记为Transactional。 CityDao自动装配。我看了很多例子,导入了所有的nessasary库,但它不起作用。

1 个答案:

答案 0 :(得分:0)

好的,所以我会给你配置:

在WEB-INF文件夹中我有2个文件:

1)hibernate-context.xml

含量:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            ">

    <context:property-placeholder location="/WEB-INF/spring.properties"/>

    <!-- Enable annotation style of managing transactions -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!-- <tx:annotation-driven/> -->

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
          p:dataSource-ref="dataSource"
          p:configLocation="${hibernate.config}"
          p:packagesToScan="com.rasp.lta"/>




    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${app.jdbc.driverClassName}"/>
        <property name="url" value="jdbc:mysql://{url to database}"/>
        <property name="username" value="{user name}"/>
        <property name="password" value="{password}"/>
    </bean>


    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
          p:sessionFactory-ref="sessionFactory">
        <qualifier value="transactionManager"/>
    </bean>


</beans>

2)hibernate.cfg.xml

含量:

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">true</property>
        <!--<property name="create">update</property>-->
    </session-factory>
</hibernate-configuration>

然后在WEB-INF中我有文件夹:spring,其中有文件root-context.xml,内容为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->

    <import resource="../hibernate-context.xml"/>
</beans>

除了在整个项目中拥有事务外,还应添加到web.xml:

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>encoding-filter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

最后在控制器中:

    @Service("linkAddress")
@Transactional
public class LinkAddressService {

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    public List<LinkAddressEntity> linkAddressEntityList(String linkList){

        Session session = sessionFactory.getCurrentSession();

           List<LinkAddressEntity> linkAddressList = (List<LinkAddressEntity>) session.getNamedQuery(LinkAddressEntity.QUERY_IN)
                                                                                                    .setString("id", linkList).list();


        return linkAddressList;

    }

}

我希望它会有所帮助。