2016-05-16 15 views
5

Sto cercando di rendere webservice basato su GenericoDao. Ho Person Entity e sto cercando di fare dao per quell'entità esclusa da GenericDao. Ma l'annotazione @Transactional non apre la transazione: TransactionSynchronizationManager.isActualTransactionActive() = falseGenericoDao: @Transactional non funziona .. di nuovo

Non riesco a trovare dove ho perso @Transactional. Ho provato ad aggiungere @Transactional quasi ovunque. Ci si sente come le annotazioni non eredita da GenericDao ..

primavera-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

Ho provato sia consigli:

metodi Overrided in PersonDaoImpl.java come questo:

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




} 

e ho cercato di impostare proxy-bersaglio-class = "false"

Entrambi non ha aiutato .. Metodo completata senza errori, ma non commesso. TransactionSynchronizationManager.isActualTransactionActive() è ancora Falso.

+1

Non mi è chiaro il motivo per cui si desidera annotare l'interfaccia. Inoltre, non c'è implementazione effettiva o alcun metodo effettivo per annotare nel tuo impl da quello che posso vedere. – Makoto

+0

Stavo solo cercando di annotare tutto dopo ore di tentativi. È vero dove non è necessario @Transactional nell'interfaccia. A proposito dell'implementazione intendi PersonDao Poppl.java? Voglio solo estenderlo da GenericDaoImpl.java senza aggiungere nuovi metodi. Stavo cercando di sovrascriverlo con l'annotazione Transazionale ma non ha funzionato. –

+0

Come è stata costruita la tua PersonDaoImpl, per la primavera? Non lo vedo nel contesto dell'applicazione ma potrebbe essere solo la parte pubblicata. – Pace

risposta

-1

Dal Spring Docs:

Primavera consiglia di annotare solo classi concrete (e metodi di classi concrete) con l'annotazione @Transactional, al contrario di interfacce Annotazione. È certamente possibile inserire l'annotazione @Transactional su un'interfaccia (o un metodo di interfaccia), ma funziona come solo come ci si aspetterebbe se si utilizzano proxy basati su interfaccia . Il fatto che le annotazioni Java non siano ereditate dalle interfacce significa che se si utilizzano i proxy basati sulla classe (proxy-target-class = "true") o l'aspetto basato sulla tessitura (mode = "aspectj"), quindi il le impostazioni della transazione non vengono riconosciute da l'infrastruttura di proxy e tessitura e l'oggetto non sarà avvolto in un proxy transazionale, il che sarebbe decisamente negativo.

Credo che i proxy basati su classi siano l'impostazione predefinita, quindi sarà necessario cambiarli o trovare un nuovo modo di risolvere il problema.

+0

Inoltre, DAO non è in genere il posto migliore in cui effettuare le transazioni (troppo vicino all'operazione), quindi non so se si tratta di un tipico caso d'uso. – Pace

+0

Vuoi dire che le annotazioni devono essere inserite in PersonDaoDao.java? –

+0

In alternativa, o modifica la modalità proxy in proxy basati su interfaccia. – Pace

Problemi correlati