【发布时间】:2017-11-25 20:17:23
【问题描述】:
我开发了一个 Spring Boot WebApplication,它接收带有一些数据的soap请求并将其保存到数据库中。 由于我是 Spring Boot 和 JPA 的初学者,因此我使用了一种常见的 JPA 配置,其中主键是 JPA 管理的 Id。
@Table(
name="MyEntity",
uniqueConstraints=@UniqueConstraint(columnNames=["channel", "service"])
)
public class MyEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id
String channel
String service
我开发了一套关于保存、搜索和修改实体的 Spock 测试,一切运行顺利。 具体来说,我有一个 Spring Boot 应用程序冒烟测试,以确保配置正确加载
@ContextConfiguration
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ApplicationContextSpec extends Specification {
@Autowired
WebApplicationContext context
def "should boot up without errors"() {
expect: "(web) application context exists"
context != null
}
}
由于自然键是渠道和服务,我尝试定义一个复合键
@Table(name="MyEntity")
@IdClass(MyEntityPk.class)
public class MyEntity {
@Id
String channel
@Id
String service
连同主键类(摘录)
public class MyEntityPk implements Serializable {
String channel
String service
@ContextConfiguration
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ApplicationContextSpec extends Specification {
@Autowired
WebApplicationContext context
def "should boot up without errors"() {
expect: "(web) application context exists"
context != null
}
}
此更改后,Spring Boot 应用程序冒烟测试失败
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
...
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
以及所有其他与 jpa 相关的测试。 作为进一步的信息,我选择了 Spring Boot gs-accessing-data-jpa-master 示例并将其适配为使用 gradle 和 spock。然后我修改为使用复合键,Spring Boot 应用程序冒烟测试按预期成功。 在我的 Ws Web 应用程序(使用依赖 spring-boot-starter-web-services)上,有些东西会导致失败。我想指出,唯一的变化是从自动生成的键移动到复合键。 这会导致找不到 EmbeddedServletContainerFactory。您对此事有什么建议吗?
我也在发布 che build 脚本,相当复杂,所以我添加了一些 cmets 来阐明实现
buildscript {
ext {
springBootVersion = '1.5.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'groovy'
apply plugin: 'org.springframework.boot'
// I am using a mixed environment with some java generated source code
// and mainly groovy classes. This sourceSets definition forces to compile
// everything with groovy compiler so that java classes see groovy classes
sourceSets {
main {
groovy {
srcDirs = ['src/main/groovy', 'src/main/java']
}
java {
srcDirs = []
}
}
test {
groovy {
srcDirs = ['src/test/groovy','src/test/java']
}
java {
srcDirs = []
}
}
}
repositories {
mavenCentral()
}
// This task defines a jaxb task that takes xsd schema definition
// and generates java classes used when mapping soap requests
task genJaxb {
ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
ext.classesDir = "${buildDir}/classes/jaxb"
ext.schema = "src/main/resources/myws.xsd"
outputs.dir classesDir
doLast() {
project.ant {
taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: configurations.jaxb.asPath
mkdir(dir: sourcesDir)
mkdir(dir: classesDir)
xjc(destdir: sourcesDir, schema: schema) {
arg(value: "-wsdl")
produces(dir: sourcesDir, includes: "**/*.java")
}
javac(destdir: classesDir, source: 1.6, target: 1.6, debug: true,
debugLevel: "lines,vars,source",
classpath: configurations.jaxb.asPath) {
src(path: sourcesDir)
include(name: "**/*.java")
include(name: "*.java")
}
copy(todir: classesDir) {
fileset(dir: sourcesDir, erroronmissingdir: false) {
exclude(name: "**/*.java")
}
}
}
}
}
configurations {
jaxb
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-web-services")
compile('org.springframework.boot:spring-boot-starter-actuator')
compile("org.codehaus.groovy:groovy-all:2.4.7")
compile("wsdl4j:wsdl4j:1.6.1")
compile(files(genJaxb.classesDir).builtBy(genJaxb))
runtime('com.h2database:h2')
jaxb("org.glassfish.jaxb:jaxb-xjc:2.2.11")
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'org.spockframework:spock-spring:1.0-groovy-2.4'
testCompile 'cglib:cglib-nodep:3.2.5'
}
jar {
baseName = 'myws'
version = '0.7.1'
excludes = ['**/application.yml']
from sourceSets.main.output
// adding jaxb generated file to be included in jar
from('build/classes/jaxb') {
include '**'
}
}
// this defines a uber-jar so that I may launch spring server
// from command line using java -jar myws-spring-boot.jar
task('execJar', type:Jar, dependsOn: 'jar') {
baseName = 'myws'
version = '0.7.1'
classifier = 'spring-boot'
from sourceSets.main.output
from('build/classes/jaxb') {
include '**'
}
}
bootRepackage {
withJarTask = tasks['execJar']
}
最后,我要做的就是:
gradlew build
构建 jar 并运行测试,然后
java -jar myws-spring-boot.jar
启动 Spring Boot 服务器
【问题讨论】:
-
你用的是什么版本的spock和spring?请发布您的 build.gradle
-
构建相当复杂,我将其添加到我的问题中
-
请尝试更新到 spock 1.1,并发布您的应用程序配置,可能您的问题出在stackoverflow.com/questions/21783391/…
标签: spring jpa gradle groovy spock