2016-05-16 13 views
5

Próbuję zrobić webservice na podstawie GenericDao. Mam Osobową Istotę i próbuję stworzyć Dao dla tej Istoty, którą rozszerzyło GenericDao. Ale adnotacja @Transactional nie otwiera transakcji: TransactionSynchronizationManager.isActualTransactionActive() = falseGenericDao: @ Transactional nie działa .. ponownie

Nie mogę znaleźć miejsca, w którym brakowało @Transactional. Próbowałem dodać prawie wszędzie @Transactional. Czuje się jak adnotacji nie dziedziczą GenericDao ..

wiosna-config.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: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> 

GenericDao.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) ; 
} 

GenericDaoImpl.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; 
    } 
} 

PersonDao.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 { 





    } 

UPDATE

próbowałem zarówno porady:

metody Overrided w PersonDaoImpl.java tak:

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); 
} 




} 

i starałem się ustawić proxy-Target-class = "false"

Obie nie pomogło .. Metoda uzupełnia bez żadnych błędów, ale nie popełnił. TransactionSynchronizationManager.isActualTransactionActive() jest nadal fałszywy.

+1

Nie jest dla mnie jasne, dlaczego chcesz opisać interfejs. Ponadto nie ma rzeczywistej implementacji ani żadnej faktycznej metody do adnotowania w impozycji z tego, co widzę. – Makoto

+0

Po prostu próbowałem opisać wszystko po wielu próbach. To prawda, gdzie nie ma potrzeby @Transactional w interfejsie. O implementacji masz na myśli PersonDaoImpl.java? Chcę tylko rozszerzyć go z GenericDaoImpl.java bez dodawania żadnych nowych metod. Próbowałem zastąpić go adnotacją transakcyjną, ale nie działało. –

+0

W jaki sposób buduje się YourDao Property, wiosną? Nie widzę go w kontekście aplikacji, ale może to być tylko część opublikowana. – Pace

Odpowiedz

-1

Z Spring Docs:

Wiosna zaleca tylko opisywanie konkretnych klas (i metod konkretnych klasach) z @Transactional adnotacji, w przeciwieństwie do interfejsów adnotacji. Z pewnością można umieścić adnotację @Transactional na interfejsie (lub na metodzie interfejsu), ale działa ona tylko w sposób, w jaki można się tego spodziewać, jeśli używane są interfejsy oparte na interfejsie . Fakt, że adnotacje Java nie są dziedziczone z interfejsów oznacza, że ​​jeśli używasz serwerów proxy opartych na klasach (proxy-target-class = "true") lub aspektu tkania (mode = "aspectj"), to ustawienia transakcji nie są rozpoznawane przez infrastrukturę proxy i tkania, a obiekt nie będzie zawinięty w proxy transakcyjne, które byłoby zdecydowanie złe.

Uważam, że domyślne są serwery oparte na klasach, więc trzeba to zmienić lub wymyślić nowy sposób rozwiązania problemu.

+0

Poza tym DAO nie jest zwykle najlepszym miejscem do zawierania transakcji (zbyt blisko operacji), więc nie wiem, czy jest to bardzo typowy przypadek użycia. – Pace

+0

masz na myśli adnotacje muszą być umieszczone w PersonDaoImpl.java? –

+0

Albo albo zmień tryb proxy na proxy oparte na interfejsie. – Pace

Powiązane problemy