2017-02-15 114 views
0

我目前正在开发一个使用cassandra作为数据库的spring boot的应用程序。由于事务管理导致的Spring Boot失败

我写了一个类来初始化我的cassandra集群。一旦我开始在DAO层查询方法中使用@Transactional,问题就会开始。系统不允许我在下面的错误信息使用它们在运行时被抛出 -

An exception has occured in method getMdoBean with msg: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available. 

我不明白什么错误。我的应用工作正常,没有弹簧启动,没有与交易管理相关的问题。

我试着添加JPA支持以及H2数据库,它解决了我的问题。我做了功课,并阅读了H2数据库及其内存数据存储机制。我无法理解TransactionManagement问题如何得到解决?是否因为H2数据库驱动程序正在处理它?

其次,我不需要H2数据库,因此这个解决方案似乎并不适合我。后端是我的应用程序的Cassandra。任何线索都会有所帮助。谢谢!

POM

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.shc.sov</groupId> 
    <artifactId>SOV</artifactId> 
    <version>4.4.0-SNAPSHOT</version> 
    <packaging>war</packaging> 
    <name>SOV</name> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.4.3.RELEASE</version> 
     <relativePath /> <!-- lookup parent from repository --> 
    </parent> 

    <properties> 
     <org.springframework.version>4.1.4.RELEASE</org.springframework.version> 
     <jersey.version>1.14</jersey.version> 
     <maven.antrun.plugin.version>1.8</maven.antrun.plugin.version> 
     <java.version>1.8</java.version> 
    </properties> 

    <repositories> 
     <repository> 
      <id>shc-central</id> 
      <name>Sears Libraries</name> 
      <url>http://obuartifactoryvip.prod.ch3.s.com/artifactory/libs-release</url> 
      <releases> 
       <enabled>true</enabled> 
      </releases> 
      <snapshots> 
       <enabled>false</enabled> 
      </snapshots> 
     </repository> 
     <repository> 
      <id>shc-snapshots</id> 
      <name>Sears Snapshot Libraries</name> 
      <url>http://obuartifactoryvip.prod.ch3.s.com/artifactory/libs-snapshot</url> 
      <releases> 
       <enabled>true</enabled> 
      </releases> 
      <snapshots> 
       <enabled>true</enabled> 
      </snapshots> 
     </repository> 
    </repositories> 



    <build> 
     <finalName>dpsserver</finalName> 
     <resources> 
      <resource> 
       <directory>src/main/resources</directory> 
       <excludes> 
        <exclude>prod/*.*</exclude> 
        <exclude>qa/*.*</exclude> 
        <exclude>stress/*.*</exclude> 
        <exclude>dev/*.*</exclude> 
        <exclude>dev-spring-boot</exclude> 
       </excludes> 
       <filtering>false</filtering> 
      </resource> 
     </resources> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-assembly-plugin</artifactId> 
       <executions> 
        <execution> 
         <id>config</id> 
         <phase>package</phase> 
         <goals> 
          <goal>single</goal> 
         </goals> 
         <configuration> 
          <descriptor>config.xml</descriptor> 
          <attach>true</attach> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <configuration> 
        <source>1.8</source> 
        <target>1.8</target> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-eclipse-plugin</artifactId> 
       <configuration> 
        <!-- Always download and attach dependencies source code --> 
        <downloadSources>true</downloadSources> 
        <downloadJavadocs>false</downloadJavadocs> 
        <!-- Avoid type mvn eclipse:eclipse -Dwtpversion=2.0 --> 
        <wtpversion>2.0</wtpversion> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-jar-plugin</artifactId> 
       <configuration> 
        <archive> 
         <manifestEntries> 
          <Class-Path>config/</Class-Path> 
         </manifestEntries> 
        </archive> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
       <version>1.4.3.RELEASE</version> 
       <executions> 
        <execution> 
         <goals> 
          <goal>repackage</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 

    <dependencies> 
     <!-- Core utilities used by other modules. Define this if you use Spring 
      Utility APIs (org.springframework.core.*/org.springframework.util.*) --> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-tomcat</artifactId> 
      <scope>provided</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-thymeleaf</artifactId> 
     </dependency> 
     <!-- <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     <exclusions> 
      <exclusion> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-starter-logging</artifactId> 
      </exclusion> 
     </exclusions> 
     </dependency> --> 
     <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa --> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 
     <!-- In memory database used by spring-boot --> 
     <!-- <dependency> 
      <groupId>com.h2database</groupId> 
      <artifactId>h2</artifactId> 
     </dependency> --> 
     <dependency> 
      <groupId>com.searshc.dce.persistence</groupId> 
      <artifactId>DcePersistence</artifactId> 
      <version>2.1</version> 
     </dependency> 
     <dependency> 
      <groupId>com.sun.jersey</groupId> 
      <artifactId>jersey-server</artifactId> 
      <version>${jersey.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>com.sun.jersey</groupId> 
      <artifactId>jersey-json</artifactId> 
      <version>${jersey.version}</version> 
      <exclusions> 
       <exclusion> 
        <artifactId>jaxb-impl</artifactId> 
        <groupId>com.sun.xml.bind</groupId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>com.sun.jersey</groupId> 
      <artifactId>jersey-client</artifactId> 
      <version>${jersey.version}</version> 
     </dependency> 

     <!-- https://mvnrepository.com/artifact/log4j/log4j --> 
     <!-- <dependency> 
      <groupId>log4j</groupId> 
      <artifactId>log4j</artifactId> 
      <version>1.2.14</version> 
     </dependency> --> 
     <!-- https://mvnrepository.com/artifact/log4j/apache-log4j-extras --> 
     <dependency> 
      <groupId>log4j</groupId> 
      <artifactId>apache-log4j-extras</artifactId> 
      <version>1.2.17</version> 
     </dependency> 

     <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> 
     <dependency> 
      <groupId>org.apache.commons</groupId> 
      <artifactId>commons-lang3</artifactId> 
      <version>3.3.2</version> 
     </dependency> 

     <dependency> 
      <groupId>commons-collections</groupId> 
      <artifactId>commons-collections</artifactId> 
      <version>3.2.1</version> 
     </dependency> 

     <dependency> 
      <groupId>commons-validator</groupId> 
      <artifactId>commons-validator</artifactId> 
      <version>1.3.1</version> 
     </dependency> 
     <dependency> 
      <groupId>commons-httpclient</groupId> 
      <artifactId>commons-httpclient</artifactId> 
      <version>3.1</version> 
     </dependency> 
     <!-- <dependency> <groupId>javax.ws.rs</groupId> <artifactId>jsr311-api</artifactId> 
      <version>1.1.1</version> </dependency> --> 

     <dependency> 
      <groupId>com.sun.jersey.contribs</groupId> 
      <artifactId>jersey-spring</artifactId> 
      <version>${jersey.version}</version> 
      <exclusions> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-core</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-web</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-beans</artifactId> 
       </exclusion> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-context</artifactId> 
       </exclusion> 
       <exclusion> 
        <artifactId>spring-aop</artifactId> 
        <groupId>org.springframework</groupId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>com.sun.xml.bind</groupId> 
      <artifactId>jaxb-impl</artifactId> 
      <version>2.2.7-b41</version> 
     </dependency> 
     <!-- <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> 
      <version>2.5</version> <scope>provided</scope> </dependency> --> 

     <dependency> 
      <groupId>com.google.code.gson</groupId> 
      <artifactId>gson</artifactId> 
      <version>1.7.2</version> 
     </dependency> 
     <!-- Unit test level dependencies --> 

     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.5</version> 
      <scope>test</scope> 
     </dependency> 
     <!-- <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> 
      <version>1.9.5</version> <scope>test</scope> </dependency> --> 
     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-cassandra</artifactId> 
      <version>1.4.6.RELEASE</version> 
      <exclusions> 
       <exclusion> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-core</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <!-- Compilation Level Dependencies --> 
     <dependency> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-antrun-plugin</artifactId> 
      <version>${maven.antrun.plugin.version}</version> 
      <scope>compile</scope> 
     </dependency> 
     <!-- DATASTAX --> 
     <dependency> 
      <groupId>com.datastax.cassandra</groupId> 
      <artifactId>cassandra-driver-core</artifactId> 
      <version>2.1.4</version> 
     </dependency> 
     <!-- DATASTAX --> 
    </dependencies> 
</project> 

卡桑德拉配置类

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.ImportResource; 
import org.springframework.context.annotation.Primary; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.core.env.Environment; 
import org.springframework.data.cassandra.config.CassandraClusterFactoryBean; 
import org.springframework.data.cassandra.config.CassandraSessionFactoryBean; 
import org.springframework.data.cassandra.config.SchemaAction; 
import org.springframework.data.cassandra.convert.CassandraConverter; 
import org.springframework.data.cassandra.convert.MappingCassandraConverter; 
import org.springframework.data.cassandra.core.CassandraOperations; 
import org.springframework.data.cassandra.core.CassandraTemplate; 
import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; 
import org.springframework.data.cassandra.mapping.CassandraMappingContext; 
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; 

import com.datastax.driver.core.PlainTextAuthProvider; 

@Configuration 
@ImportResource("application-context.xml") 
@PropertySource(value = { "classpath:cassandra.properties" }) 
@EnableCassandraRepositories(basePackages = {"com.spring.sample"}) 
public class CassandraDsConfig { 

    @Autowired 
    private Environment env; 

    @Bean 
    public CassandraClusterFactoryBean configureCassandraCluster() { 
     CassandraClusterFactoryBean clusterFactory = new CassandraClusterFactoryBean(); 
     clusterFactory.setContactPoints(env.getProperty("cassandra.Newcontactpoints")); 
     clusterFactory.setPort(Integer.parseInt(env.getProperty("cassandra.Newport"))); 
     PlainTextAuthProvider plainTextAuthProvider = new PlainTextAuthProvider(env.getProperty("cassandra.username"), 
       env.getProperty("cassandra.password")); 

     clusterFactory.setAuthProvider(plainTextAuthProvider); 
     return clusterFactory; 
    } 

    @Bean 
    public CassandraMappingContext mappingContext() { 
     return new BasicCassandraMappingContext(); 
    } 

    @Bean 
    public CassandraConverter converter() { 
     return new MappingCassandraConverter(mappingContext()); 
    } 

    @Bean 
    public CassandraSessionFactoryBean session() throws Exception { 
     CassandraSessionFactoryBean session = new CassandraSessionFactoryBean(); 
     session.setCluster(configureCassandraCluster().getObject()); 
     session.setKeyspaceName(env.getProperty("cassandra.Newkeyspace")); 
     session.setConverter(converter()); 
     session.setSchemaAction(SchemaAction.NONE); 

     return session; 
    } 

    @Primary 
    @Bean("cassandraNewTemplate") 
    public CassandraOperations cassandraNewTemplate() throws Exception { 
     return new CassandraTemplate(session().getObject()); 
    } 
} 

春季启动主类

import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 
import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.boot.web.support.SpringBootServletInitializer; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Import; 
import org.springframework.context.annotation.ImportResource; 
import org.springframework.context.annotation.PropertySource; 
//import org.springframework.context.annotation.PropertySource; 
import org.springframework.boot.Banner; 


/** 
* @author bnarula 
* 
*/ 
@SpringBootApplication 
@ImportResource("application-context.xml") 
@Import(CassandraDsConfig.class) 
@PropertySource("dps.properties") 
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) 
@ComponentScan(basePackages = "com.shc.marketplace.ias") 
public class DPSMainModule extends SpringBootServletInitializer { 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 
     return configureApplication(builder); 
    } 

    public static void main(String[] args) { 
     configureApplication(new SpringApplicationBuilder()).run(args); 
    } 

    private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) { 
     return builder.sources(DPSMainModule.class).bannerMode(Banner.Mode.OFF); 
    } 
} 

DAO层类的缓存 -

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 

import org.apache.log4j.Logger; 
import org.springframework.beans.BeanUtils; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.cassandra.core.CassandraOperations; 
import org.springframework.transaction.annotation.Transactional; 

import com.datastax.driver.core.querybuilder.QueryBuilder; 
import com.datastax.driver.core.querybuilder.Select; 
import com.searshc.dce.persistence.DcePersistence.dao.beans.FreightAreaBean; 
import com.searshc.dce.persistence.DcePersistence.dao.beans.FreightAreaPOJO; 
import com.shc.scinventory.dps.server.dao.CacheBuilderDAO; 
import com.shc.scinventory.dps.server.model.StoretoRRCPOJO; 
import com.shc.scinventory.dps.server.model.ZiptoWarehousePOJO; 

public class CacheBuilderDAOImpl implements CacheBuilderDAO { 

    private static Logger logger = Logger.getLogger(CacheBuilderDAOImpl.class); 

    private Map<String, String> storeToRRCMap = new HashMap<String, String>(); 
    private Map<String, String> ziptoWarehouseMap = new HashMap<String, String>(); 
    private Map<String, List<FreightAreaBean>> zipToFaMap = new HashMap<String, List<FreightAreaBean>>(); 
    List<StoretoRRCPOJO> storeToRRCList = new ArrayList<StoretoRRCPOJO>(); 

    public List<StoretoRRCPOJO> getStoreToRRCList() { 
     return storeToRRCList; 
    } 

    public void setStoreToRRCList(List<StoretoRRCPOJO> storeToRRCList) { 
     this.storeToRRCList = storeToRRCList; 
     for (StoretoRRCPOJO storetoRRCBean : storeToRRCList) { 
      storeToRRCMap.put(storetoRRCBean.getStore(), storetoRRCBean.getRrc()); 
     } 
    } 

    @Autowired 
    private CassandraOperations cassandraOperations; 
    private String keyspace; 

    @Override 
    public void initStatements() { 
     logger.debug("CacheBuilderDAOImpl : Inside method init"); 
     if (cassandraOperations == null) { 
      logger.error("Cassandra not available"); 
     } else { 
      List<ZiptoWarehousePOJO> ziptoWarehouseList = getZiptoWarehouseMapping(); 
      List<StoretoRRCPOJO> storetoRRCList = getStoretoRRCMapping(); 

      for (ZiptoWarehousePOJO ziptoWarehouseBean : ziptoWarehouseList) { 
       ziptoWarehouseMap.put(ziptoWarehouseBean.getDestinationZip(), ziptoWarehouseBean.getDcUnit()); 
      } 

      setStoreToRRCList(storetoRRCList); 

      refreshZipToFaMapping(); 

     } 
    } 

    public void refreshZipToFaMapping() { 
     zipToFaMap = getZipToFAMapping(); 
    } 

    @Transactional 
    public Map<String, List<FreightAreaBean>> getZipToFAMapping() { 
     logger.debug("Inside method getZipToFAMapping"); 
     Map<String, List<FreightAreaBean>> result = new HashMap<String, List<FreightAreaBean>>(); 
     try { 
      Select select = QueryBuilder.select().all().from("capacity", "freight_area"); 
      List<FreightAreaPOJO> queryResult = cassandraOperations.select(select, FreightAreaPOJO.class); 

      for(FreightAreaPOJO faPOJO : queryResult) { 
       String zip = faPOJO.getGeocode_no(); 
       if(!result.containsKey(zip)) { 
        result.put(zip, new LinkedList<FreightAreaBean>()); 
       } 
       FreightAreaBean faBean = new FreightAreaBean(); 
       BeanUtils.copyProperties(faPOJO, faBean); 
       result.get(zip).add(faBean); 
      } 
     } catch (Exception e) { 
      logger.error("getZipToFAMapping Error while fetch data from DB: " + e.getMessage()); 
      e.printStackTrace(); 
     } 
     logger.debug("Exiting method getZipToFAMapping"); 
     return result; 
    } 

    public List<ZiptoWarehousePOJO> getZiptoWarehouseMapping() { 
     logger.debug("Inside method getZiptoWarehouseMapping"); 
     List<ZiptoWarehousePOJO> result = null; 
     try { 
      Select select = QueryBuilder.select().all().from(getKeyspace(), "ziptowarehouse"); 
      result = cassandraOperations.select(select, ZiptoWarehousePOJO.class); 
     } catch (Exception e) { 
      logger.error("getZiptoWarehouseMapping Error while fetch data from DB: " + e.getMessage()); 
     } 
     logger.debug("Exiting method getZiptoWarehouseMapping"); 
     return result; 
    } 

    public List<StoretoRRCPOJO> getStoretoRRCMapping() { 
     logger.debug("Inside method getStoretoRRCMapping"); 
     List<StoretoRRCPOJO> result = null; 
     try { 
      Select select = QueryBuilder.select().all().from(getKeyspace(), "storetorrc"); 
      result = cassandraOperations.select(select, StoretoRRCPOJO.class); 
     } catch (Exception e) { 
      logger.error("getStoretoRRCMapping Error while fetch data from DB: " + e.getMessage()); 
     } 
     logger.debug("Exiting method getStoretoRRCMapping"); 
     return result; 
    } 

    public String getKeyspace() { 
     return keyspace; 
    } 

    public void setKeyspace(String keyspace) { 
     this.keyspace = keyspace; 
    } 

    public Map<String, String> getStoreToRRCMap() { 
     return storeToRRCMap; 
    } 

    public void setStoreToRRCMap(Map<String, String> storeToRRCMap) { 
     this.storeToRRCMap = storeToRRCMap; 
    } 

    public Map<String, String> getZipToWarehouseMap() { 
     return ziptoWarehouseMap; 
    } 

    public void setZiptoWarehouseMap(Map<String, String> ziptoWarehouseMap) { 
     this.ziptoWarehouseMap = ziptoWarehouseMap; 
    } 

    public Map<String, List<FreightAreaBean>> getZipToFaMap() { 
     return zipToFaMap; 
    } 

    public void setZipToFaMap(Map<String, List<FreightAreaBean>> zipToFaMap) { 
     this.zipToFaMap = zipToFaMap; 
    } 


} 

如果我在方法级别上面的类中使用@Transactional,它不允许没有为JPA添加H2支持。在POM中放置下面的代码行后它工作正常。

<dependency> 
     <groupId>com.h2database</groupId> 
     <artifactId>h2</artifactId> 
    </dependency> 
+0

不能没有代码.. – Jaiwo99

+0

@ Jaiwo99 ..添加代码。 – Bhaskar

回答

0

我想原因是你排除HibernateJpaAutoConfiguration,没有任何理由这样做,否则我会建议你将它添加回去,也许还可以添加@EnableTransactionManagement到您的配置类。

+0

它也不这样工作。试过了。 – Bhaskar

+0

@Bhaskar然后你需要提供堆栈跟踪。这个注释会为你提供事务管理器..如果它不能解决你的问题,你就会在其他地方遇到问题。 – Jaiwo99