我目前正在开发一个使用带有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>
答案 0 :(得分:0)
我猜原因是你排除了HibernateJpaAutoConfiguration
,有没有理由这样做,否则我建议你把它添加回去,也可以在你的配置类中添加@EnableTransactionManagement
。