Invalid query created by hibernate - spring boot 3 - spring-boot

I have a small application that uses spring boot 2.7.4 and Spring data JPA to connect to AS400. Its been working fine. Now I am trying to upgrade it to spring boot 3 and getting this error
ERROR 10876 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select * from (select s1_0.id c0,s1_0.message c1,row_number() over() rn from table1 s1_0) r_0_ where order by r_0_.rn]] with root cause
com.ibm.as400.access.AS400JDBCSQLSyntaxErrorException: [SQL0199] Keyword BY not expected. Valid tokens: < > = <> <= !< !> != >= ¬< ¬> ¬= IN NOT.
at com.ibm.as400.access.JDError.createSQLExceptionSubClass(JDError.java:948) ~[jt400-11.1.jar:JTOpen 11.1]
I am not sure why it is creating a second select statement(with wrong syntax) to enclose the seemingly correct select statement.
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.0'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'net.sf.jt400', name: 'jt400', version: '11.1'
implementation 'org.springframework.boot:spring-boot-starter-web'
//implementation 'com.ibm.db2:jcc'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
properties
spring.datasource.driver-class-name=com.ibm.as400.access.AS400JDBCDriver
spring.datasource.username=**
spring.datasource.password=**
spring.datasource.url=jdbc:as400://**
spring.datasource.hikari.connection-test-query:values 1
spring.jpa.generate-ddl=false
Using JPA repository
public interface Table1Repository extends JpaRepository<Table1, Long> {
}
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
#Entity
#Table(name = "TABLE1")
public class Table1 {
#Id
private Long id;
private String message;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
this is the call that is causing this error
tablel1Repository.findAll();
It was working fine with spring boot 2.7.4 and with SB 3.0.0 it is not.

select s1_0.id c0,s1_0.message c1,row_number() over() rn from table1 s1_0) r_0_ where order by r_0_.rn
where order by
Is not valid SQL syntax. I don't why SB 3 would be trying that, but you might look to see if it's an open issue.

Related

Spring Boot Resilience4j circuit breaker and fall back not implementing

I have a simple rest api with Resilience4j implementation but for some reason the circuit breaker or fallback implementation is not working. I am not sure If I am using right dependency. I have a simple member-info-api which consume another api called benefit-api. I have implemented the circuit breaker on benefit api call and a logic to create a timeout exception. When it is run its still wait on the timeout and then throw the TimeOutException. Look like my Circuit breaker is not being implemented. here is my code:
build.gradle
plugins {
id 'org.springframework.boot' version '2.7.2'
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id 'java'
}
group = 'com.thomsoncodes'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2021.0.3")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
controller class
#RestController
public class WebController {
public static final Logger LOG = LoggerFactory.getLogger(WebController.class);
#Autowired
private MemberInfoService memberInfoService;
#GetMapping("member/{memId}")
public ResponseEntity<MemberInfo> memberInfo(#PathVariable("memId") String memId) throws TimeoutException {
LOG.info("---Beginning of the WebController.methodmemberInfo()---");
MemberInfo resp = null;
resp = memberInfoService.getMemberInfo(memId);
LOG.info("---End of the WebController.methodmemberInfo()---");
return new ResponseEntity<MemberInfo>(resp, (HttpStatus.OK));
}
}
MemberInfoService.java
#Service
public class MemberInfoService {
public static final Logger LOG = LoggerFactory.getLogger(MemberInfoService.class);
#Autowired
private UserInfoService userInfoService;
#Autowired
private BenefitService benefitService;
public MemberInfo getMemberInfo(String memId) throws TimeoutException {
LOG.info("---End of the WebController.MemberInfoService()---");
MemberInfo memberInfo = null;
memberInfo = userInfoService.getUserInfo(memId);
Benefit benefit = null;
benefit = benefitService.getBenefitInfo(memId);
memberInfo.setBenefit(benefit);
LOG.info("---End of the WebController.MemberInfoService()---");
return memberInfo;
}
}
BenefitService.java
#Service
public class BenefitService {
public static final Logger LOG = LoggerFactory.getLogger(BenefitService.class);
#Autowired
private WebClient benefitApiClient;
#CircuitBreaker(name = "benefitService", fallbackMethod = "buildFallbackBenefitInfo")
#RateLimiter(name = "benefitService", fallbackMethod = "buildFallbackBenefitInfo")
#Retry(name = "retryBenefitService", fallbackMethod = "buildFallbackBenefitInfo")
public Benefit getBenefitInfo(String memId) throws TimeoutException {
LOG.info("---Beginning of the BenefitService.getBenefitInfo()---");
randomlyRunLong();
return benefitApiClient.get()
.uri("/member/benefit/" + memId)
.retrieve()
.bodyToMono(Benefit.class)
.block();
}
public Benefit buildFallbackBenefitInfo(String memId, Throwable t) throws TimeoutException {
Benefit benefit = null;
benefit = new Benefit();
benefit.setBenefitId("00000");
benefit.setMemeberId("00000");
return benefit;
}
private void randomlyRunLong() throws TimeoutException{
Random rand = new Random();
int randomNum = rand.nextInt((3 - 1) + 1) + 1;
if (randomNum==3) sleep();
}
private void sleep() throws TimeoutException{
try {
System.out.println("Sleep");
Thread.sleep(5000);
throw new java.util.concurrent.TimeoutException();
} catch (InterruptedException e) {
LOG.error(e.getMessage());
}
}
}
application.yml
server:
port: 9095
management.endpoints.enabled-by-default: false
management.endpoint.health:
enabled: true
show-details: always
resilience4j.circuitbreaker:
instances:
benefitService:
registerHealthIndicator: true
ringBufferSizeInClosedState: 5
ringBufferSizeInHalfOpenState: 3
waitDurationInOpenState: 10s
failureRateThreshold: 50
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
- java.util.concurrent.TimeoutException
- org.springframework.web.client.ResourceAccessException
resilience4j.ratelimiter:
instances:
benefitService:
limitForPeriod: 5
limitRefreshPeriod: 5000
timeoutDuration: 1000ms
resilience4j.retry:
instances:
retryBenefitService:
maxRetryAttempts: 5
waitDuration: 10000
retry-exceptions:
- java.util.concurrent.TimeoutException
resilience4j.bulkhead:
instances:
bulkheadBenefitService:
maxWaitDuration: 2ms
maxConcurrentCalls: 20
resilience4j.thread-pool-bulkhead:
instances:
bulkheadBenefitService:
maxThreadPoolSize: 1
coreThreadPoolSize: 1
queueCapacity: 1
I am not sure what wrong I am doing here. A help would be really appreciated. Thanks in advance
The default Resilience4j aspect order is
Retry( CircuitBreaker( RateLimiter( TimeLimiter( Bulkhead( function)))))
Your RateLimiter has a fallback, so it never throws an exception, so CircuitBreaker never sees a failed invocation. Specify a fallback on only the last aspect that will execute.

SpringBoot Service Injection using private final not working

I am new to springboot and am trying to follow this example: https://github.com/eugenp/tutorials/tree/master/spring-caching-2
In my app I keep getting "error: variable myApplicationService not initialized in the default constructor" but in comparison to the tutorial I am following, I don't understand how it gets initialized, this is my controller:
package com.springbootredis.controllers;
import com.springbootredis.service.MyApplicationService;
import lombok.AllArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
#RestController
#AllArgsConstructor
#RequestMapping(value = "/person", produces = { MediaType.APPLICATION_JSON_VALUE })
public class PersonController {
private final MyApplicationService myApplicationService;//ERROR HERE
#GetMapping("/uuid")
public String generateRandomUUID() {
return UUID.randomUUID().toString();
}
#GetMapping("/addperson/{name}")
public String addPerson(#PathVariable String name) {
String ret = myApplicationService.addNewPerson(name);
return "Added person with name: " + name + " and id: " + ret;
}
#GetMapping("/deleteperson/{id}")
public String deletePerson(#PathVariable String id) {
String ret = myApplicationService.delete(id);
return "Deleted person. ID:" + id + " Name: " + ret;
}
#GetMapping("/updateperson/{id}/{name}")
public String updatePerson(#PathVariable String id, #PathVariable String name) {
myApplicationService.updatePerson(id, name);
return "Updated person. ID:" + id + " with Name: " + name;
}
#GetMapping("/getperson/{id}")
public String getPerson(#PathVariable String id) {
String ret = myApplicationService.findById(id);
return "Got person. ID:" + id + " Name: " + ret;
}
}
I tried autowired annotation but it says it is not recommended, and the build still fails. My build.gradle looks like this:
plugins {
id 'org.springframework.boot' version '2.7.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'war'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-data-redis:2.7.0")
implementation("org.springframework.boot:spring-boot-starter-cache:2.7.1")
implementation("org.projectlombok:lombok:1.18.24")
implementation("org.springframework.boot:spring-boot-dependencies:2.7.1")
runtimeOnly("mysql:mysql-connector-java:8.0.29")
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
Any help/pointers would be much appreciated.
Edit: (For completeness' sake) As you've already found out, the annotationProcessor entry for Lombok is missing from your build.gradle file. In addition, your Lombok entry can be compileOnly and does not need to be included at runtime.
Original Answer follows.
Your code as-is should still work. As mentioned by #m-deinum, you should also avoid doing manual dependency management on Spring versions.
That said, Lombok does its magic via Annotation Processing, a feature that might not be enabled by default in your IDE Project.
One possible culprit for your error is that this feature is disabled, hence Lombok is not generating the constructor and only a default, no-args constructor is available. Once you enable it, the compile-error should go away.
That said, I've found #AllArgsConstructor to not be very robust when designing classes. Prefer #RequiredArgsConstructor or simply explicit constructors and design your classes to have immutable state.
To resolve my issue I added the following to the build.gradle file under the dependencies section:
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
annotationProcessor("org.projectlombok:lombok:1.18.24")

NoSuchMethodException QueryDSL with Spring Boot & Spring Data Mongo

I am trying to implement Query DSL on my Spring Boot 2.0.4.RELEASE app that uses Spring Data Mongo 2.0.4.RELEASE & Gradle 4.10.
I am using Spring Tool Suite for running it locally.
Did the following steps which I found from multiple sources including Spring data documentation:
created gradle/querydsl.gradle which has below content to generate Q classes
apply plugin: "com.ewerk.gradle.plugins.querydsl"
sourceSets {
main {
java {
srcDir "$buildDir/generated/source/apt/main"
}
}
}
querydsl {
springDataMongo = true
querydslSourcesDir = "$buildDir/generated/source/apt/main"
}
dependencies {
compile "com.querydsl:querydsl-mongodb:4.1.4"
compileOnly "com.querydsl:querydsl-apt:4.1.4"
}
sourceSets.main.java.srcDirs = ['src/main/java']
Calling above gradle file from main build.gradle as shown below
buildscript {
ext { springBootVersion = "2.0.4.RELEASE" }
repositories { mavenCentral() }
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.9"
}
}
plugins {
id "java"
id "eclipse"
id "org.springframework.boot" version "2.0.4.RELEASE"
id "io.spring.dependency-management" version "1.0.6.RELEASE"
}
sourceCompatibility = 1.8
repositories { mavenCentral() }
dependencies {
...
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootVersion}")
...
}
apply from: 'gradle/querydsl.gradle'
/* Added this because Eclipse was not able to find generated classes */
sourceSets.main.java.srcDirs = ['build/generated/source/apt/main','src/main/java']
compileJava.dependsOn processResources
processResources.dependsOn cleanResources
After this updated the Repository annotated interface as below. Note: I also use Fragment Repository FragmentOrderRepository for some custom queries.
public interface OrderRepository<D extends OrderDAO>
extends EntityRepository<D>, PagingAndSortingRepository<D, String>, FragmentOrderRepository<D>, QuerydslPredicateExecutor<D> {}
Then in controller created a GET mapping as shown here
#RestController
public class OrderController {
#GetMapping(value="/orders/dsl", produces = { "application/json" })
public ResponseEntity<List> getOrdersDSL(#QuerydslPredicate(root = OrderDAO.class) Predicate predicate, Pageable pageable, #RequestParam final MultiValueMap<String, String> parameters) {
return (ResponseEntity<List>) orderService.getTools().getRepository().findAll(predicate, pageable);
}
}
Then in my runner class I added EnableSpringDataWebSupport annotation
#SpringBootApplication
#EnableSpringDataWebSupport
public class SampleApp {
public static void main(String[] args) {
SpringApplication.run(SampleApp.class, args);
}
}
With this my app starts up without any errors but when I try hitting the path http://localhost:5057/orders/dsl?email=test#test.com
I get a NoSuchMethodException with message No primary or default constructor found for interface com.querydsl.core.types.Predicate.
Can anyone please help with some pointers to solve this issue?
It seems that parameters are not getting resolved to a type.
---- UPDATE 09/19/19 ----
While debugging I found that a class HandlerMethodArgumentResolverComposite which finds ArgumentResolver for given MethodParameter from a List of argumentResolvers(of type HandlerMethodArgumentResolver). This list does not contain QuerydslPredicateArgumentResolver. Hence it is not able to resolve the arguments.
This means QuerydslWebConfiguration which adds above resolver for Predicate type is not getting called, which in turn indicates that some AutoConfiguration is not happening.
Probably I am missing some annotation here.
Found the mistake I was doing, was missing EnableWebMvc annotation on my Configuration annotated class.
Details are in this documentation.

Circular view path [error] while json output expected in springboot

newbie to Springboot with gradle, I am creating a restful service which queries the db2 database and returns the result in json.
The desired output
{
resource: {
results: [
{
currencyCode: "JPY",
conversionRateToUSD: "0.010286580",
conversionRateFromUSD: "97.214040040",
startDate: "2011-01-01",
endDate: "2011-01-29"
}
]
}
}
The api i am trying to build is http://localhost:8080/apis/exchange-rates/referenceDate=2015-01-01&currencyCode=JPY
I have created the below controller class
#RestController
#Slf4j
#RequestMapping("/apis")
public class IndividualExchangeRateController {
#Autowired
private IndividualExchangeRateService individualExchangeRateService;
public IndividualExchangeRateController(IndividualExchangeRateService individualExchangeRateService) {
this.individualExchangeRateService = individualExchangeRateService;
}
#RequestMapping(value = "/exchange-rates", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
public #ResponseBody IndividualResource getIndividual(#RequestParam("referenceDate") #DateTimeFormat(pattern = "YYYY-MM-DD")Date referenceDate,
#RequestParam(value = "currencyCode", required = false) String currencyCode){
try {
System.out.println("Inside Controller");
return individualExchangeRateService.getIndividualExchangeRate(referenceDate, currencyCode);
}
catch (HttpClientErrorException e){
throw new InvalidRequestException(e.getMessage());
}
}
}
I am getting the below error when i call the api
javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
Can anybody help out on this ?
As the output is json i do not have thymeleaf dependencies on my application
Below is the gradle build file
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.abc.service'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url "http://artifactory.abcinc.dev/artifactory/maven-repos" }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compileOnly 'org.projectlombok:lombok:1.18.8'
annotationProcessor 'org.projectlombok:lombok:1.18.8'
runtime 'com.ibm.db2.jcc:db2jcc4:4.19.49'
compile group: 'org.springframework', name: 'spring-jdbc', version: '5.1.9.RELEASE'
compile group: 'com.zaxxer', name: 'HikariCP', version: '3.3.1'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.9'
}
public class IndividualExchangeRate {
private String currencyCode;
private double conversionRateFromUSD;
private double conversionRateToUSD;
}
public class IndividualResource {
private List<IndividualExchangeRate> individualExchangeRates;
}
All the classes are annotated with lombok.
Spring Boot uses a default Whitelabel error page in case server error.So there might be some code snippets which is breaking your appliaction flow.
Add server.error.whitelabel.enabled=false in your application.properties file .
OR add the following code snippets :
#Controller
public class AppErrorController implements ErrorController{
private static final String PATH = "/error";
#RequestMapping(value = PATH)
public String error() {
return "Error handling";
}
#Override
public String getErrorPath() {
return PATH;
}
}

Spock test fails when using JPA Composite Key on Groovy/Gradle build

I developed a Spring Boot WebApplication that receives a soap request with some data and save it to database.
As I am a kind of beginner on Spring Boot and JPA, I used a commonly found configuration for JPA where the primary key is an Id managed by JPA.
#Table(
name="MyEntity",
uniqueConstraints=#UniqueConstraint(columnNames=["channel", "service"])
)
public class MyEntity {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
Long id
String channel
String service
I developed a set of Spock test about saving, searching and modifying entity and everything runs smoothly.
Specifically I have a Spring Boot application smoke test to be sure that configuration load correctly
#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
}
}
As the natural key is channel and service, I tried to define a composite key
#Table(name="MyEntity")
#IdClass(MyEntityPk.class)
public class MyEntity {
#Id
String channel
#Id
String service
along with the primary key class (excerpt)
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
}
}
After this change, Spring Boot application smoke test fails with
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.
along with all other jpa related tests.
As a further information, I picked Spring Boot gs-accessing-data-jpa-master sample and adapter it to use gradle and spock. Then I modified to use a composite key and Spring Boot application smoke test is successful as expected.
On my Ws Web Application (uses dependency spring-boot-starter-web-services) there is something that causes failure. I would like to point out that the only changes were moving from auto generated key to composite key.
This causes failure to find EmbeddedServletContainerFactory. Do you have any suggestion on the matter ?
I am posting also che build script, quite complex so I added some comments to clarify implementation
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']
}
Eventually, all I have to do is:
gradlew build
to build the jar and run the tests and then
java -jar myws-spring-boot.jar
to launch the spring boot server
Smoke test was not working because I did not perform all required changes when moving from the "Long id" field as primary key
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
Long id
to
#Id
String channel
#Id
String service
I forgot to remove a method in the repository class that was referencing the "Long id" field. After moving to spring-spock 1.1 following Leonard Brünings' suggestion, I got a more detailed error message that pointed me to the right direction.
Error creating bean with name 'modelEntryRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property id found for type ModelEntryEntity!
So I removed the references (method declaration in repository interface) and smoke test ended successfully.
By the way, within build.gradle I had to add spock core explicitly, so instead of one line with reference to spring-spock 1.0 I had to put
testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
testCompile 'org.spockframework:spock-spring:1.1-groovy-2.4'

Resources