事务管理引起的Spring Boot失败

时间:2017-02-15 12:02:21

标签: spring spring-boot cassandra spring-data-jpa

我目前正在开发一个使用带有cassandra作为数据库的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>

Cassandra配置类

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

Spring Boot Main Class

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支持的情况下使用@Transactional。在POM中放置下面的代码行后,它工作正常。

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

1 个答案:

答案 0 :(得分:0)

我猜原因是你排除了HibernateJpaAutoConfiguration,有没有理由这样做,否则我建议你把它添加回去,也可以在你的配置类中添加@EnableTransactionManagement