GenericDao:@Transactional再也没有工作了

时间:2016-05-16 00:48:13

标签: java spring hibernate

我试图基于GenericDao制作网络服务。我有Person Entity,我试图为GenericDao扩展的Entity制作dao。但console注释不会打开事务:@Transactional

我无法找到我错过的地方TransactionSynchronizationManager.isActualTransactionActive() = false。我试图几乎到处都添加@Transactional。感觉就像注释没有继承GenericDao ..

弹簧-config.xml中


    @Transactional

GenericDao.java

<?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:tx="http://www.springframework.org/schema/tx"
      xmlns:p="http://www.springframework.org/schema/p"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd">

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

      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://127.0.0.1:5432/test" />
        <property name="username" value="postgres" />
        <property name="password" value="postgress" />
      </bean>

      <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="annotatedClasses">
        <list>
        <value>org.entity.nci.person.Person</value>
        </list>
        </property>
        <property name="hibernateProperties">
          <props>
            <prop 
             key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>

          </props>
        </property>
        <property name="packagesToScan" value="com.byteslounge.spring.tx.model" />
      </bean>

      <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager" 
        p:sessionFactory-ref="sessionFactory">
      </bean>
      <tx:advice id="transactionAdvice" transaction-manager="transactionManager">  
      <tx:attributes>    
        <tx:method name="*"/>
      </tx:attributes>
      </tx:advice>

    </beans>
    

GenericDaoImpl.java

package org.dao.nci.person;

import java.io.Serializable;
import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebService;

import org.springframework.transaction.annotation.Transactional;

public interface GenericDao<E,K> {
    @WebMethod(exclude = true)
    public String add(List<E> entities) ;
    @WebMethod(exclude = true)
    public String saveOrUpdate(E entity) ;
    @WebMethod(exclude = true)
    public String update(E entity, String whereClause) ;
    @WebMethod(exclude = true)
    public String remove(E entity);
    @WebMethod(exclude = true)
    public E find(K key);
    @WebMethod(exclude = true)
    public List<E> get(String whereClause) ;
}

PersonDao.java

package org.dao.nci.person;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.jws.WebService;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@SuppressWarnings("unchecked")
@Repository

public abstract class GenericDaoImpl<E, K extends Serializable> 
        implements GenericDao<E, K> {
    @Autowired
    private SessionFactory sessionFactory;

    protected Class<? extends E> daoType;

    public GenericDaoImpl() {
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        daoType = (Class) pt.getActualTypeArguments()[0];
    }

    protected Session currentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    @Transactional
    public String add(List<E> entities) {
        for(Object entity : entities){
            currentSession().save(entity);
        }
        return "test";
    }

    @Override
    @Transactional
    public String saveOrUpdate(E entity) {
        currentSession().saveOrUpdate(entity);
        return "test";
    }

    @Override
    @Transactional
    public String update(E entity, String whereClause) {
        currentSession().saveOrUpdate(entity);
        return "test";
    }

    @Override
    @Transactional
    public  String remove(E entity) {
        currentSession().delete(entity);
        return "test";
    }

    @Override
    @Transactional
    public E find(K key) {
        Session session = currentSession();

        Transaction transaction = session.beginTransaction();

        transaction.commit();

        //session.close();
        return (E) session.get(daoType, key);
    }


    @Override
    @Transactional
    public List<E> get(String filter) {
        List<E> records =  currentSession().createCriteria(daoType).list();
        return records;
    }
}

PersonDaoImpl.java

package org.dao.nci.person;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlRootElement;

import org.entity.nci.person.Person;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@WebService
@XmlRootElement(name = "ComplexService")
@Transactional
public interface PersonDao extends GenericDao<Person, String>{



    @WebMethod(operationName = "selectPerson")
    @WebResult(name="row")
    @Override
    @Transactional
    public List<Person> get(@WebParam(name="filter") String whereClause);
    @WebMethod(operationName = "insertPerson")
    @Override
    @Transactional
    public String add(@WebParam(name="row") List<Person> persons);

}

更新

我尝试了两个建议:

PersonDaoImpl.java 中的覆盖方法如下:

package org.dao.nci.person;

import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebService;

import org.entity.nci.person.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;



@WebService(endpointInterface = "example.catalog.ProductCatalogService",
serviceName = "ProductCatalogService")
@Repository
@Transactional
public class PersonDaoImpl extends GenericDaoImpl<Person, String> 
                        implements PersonDao {





    }

我试图设置proxy-target-class =“false”

两者都没有帮助..方法完成没有任何错误但没有提交。 package org.dao.nci.person; import java.util.List; import javax.jws.WebParam; import javax.jws.WebService; import org.entity.nci.person.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionSynchronizationManager; @WebService(endpointInterface = "example.catalog.ProductCatalogService", serviceName = "ProductCatalogService") public class PersonDaoImpl extends GenericDaoImpl<Person, String> implements PersonDao { @Override @Transactional public String add(List<Person> entities){ return super.add(entities); } } 仍然是假的。

1 个答案:

答案 0 :(得分:-1)

来自Spring Docs

  

Spring建议您只注释具体的类(和方法)   带有@Transactional注释的具体类),而不是   注释接口。你当然可以放置@Transactional   接口(或接口方法)上的注释,但这是有效的   只有在你使用基于接口的情况下才会如你所愿   代理。 Java注释不是从中继承的事实   接口意味着如果您使用基于类的代理   (proxy-target-class =&#34; true&#34;)或基于编织的方面   (mode =&#34; aspectj&#34;),然后无法识别交易设置   代理和编织基础设施,而对象不会   包含在事务代理中,这将是非常糟糕的。

我认为基于类的代理是默认的,因此您需要更改它或提出解决问题的新方法。