Error: io.lettuce.core.RedisConnectionException Unable to connect to localhost/<unresolved> - spring-boot

I'm trying this tutorial from a book where there's an api running and when the application with the redis code gets called, it's suppose to output the information from the api. However, this is the error I get when I run the application:
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689) ~[spring-data-redis-2.6.3.jar:2.6.3]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597) ~[spring-data-redis-2.6.3.jar:2.6.3]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1383) ~[spring-data-redis-2.6.3.jar:2.6.3]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1366) ~[spring-data-redis-2.6.3.jar:2.6.3]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1093) ~[spring-data-redis-2.6.3.jar:2.6.3]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:421) ~[spring-data-redis-2.6.3.jar:2.6.3]
at com.demo.springdataexample.demo.PlaneFinderPoller.pollPlanes(PlaneFinderPoller.java:25) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.3.18.jar:5.3.18]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) ~[lettuce-core-6.1.8.RELEASE.jar:6.1.8.RELEASE]
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56) ~[lettuce-core-6.1.8.RELEASE.jar:6.1.8.RELEASE]
at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:330) ~[lettuce-core-6.1.8.RELEASE.jar:6.1.8.RELEASE]
at io.lettuce.core.RedisClient.connect(RedisClient.java:216) ~[lettuce-core-6.1.8.RELEASE.jar:6.1.8.RELEASE]
at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:115) ~[spring-data-redis-2.6.3.jar:2.6.3]
at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:115) ~[spring-data-redis-2.6.3.jar:2.6.3]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1595) ~[spring-data-redis-2.6.3.jar:2.6.3]
... 17 common frames omitted
Below is the code:
Main class:
package com.demo.springdataexample.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
#SpringBootApplication
public class SburRedisApplication {
#Bean
public RedisOperations<String, Aircraft>
redisOperations(RedisConnectionFactory factory) {
Jackson2JsonRedisSerializer<Aircraft> serializer =
new Jackson2JsonRedisSerializer<>(Aircraft.class);
RedisTemplate<String, Aircraft> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setDefaultSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
return template;
}
public static void main(String[] args) {
SpringApplication.run(SburRedisApplication.class, args);
}
}
PlaneFinderPoller.java
package com.demo.springdataexample.demo;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
#EnableScheduling
#Component
public class PlaneFinderPoller {
private WebClient webclient =
WebClient.create("http://localhost:7634/aircraft");
private final RedisConnectionFactory connectionFactory;
private final RedisOperations<String, Aircraft> redisOperations;
public PlaneFinderPoller(RedisConnectionFactory connectionFactory,
RedisOperations<String, Aircraft> redisOperations)
{
this.connectionFactory = connectionFactory;
this.redisOperations = redisOperations;
}
#Scheduled(fixedRate = 1000)
private void pollPlanes(){
connectionFactory.getConnection().serverCommands().flushDb();
webclient.get()
.retrieve()
.bodyToFlux(Aircraft.class)
.filter(plane -> !plane.getReg().isEmpty())
.toStream()
.forEach(ac -> redisOperations.opsForValue().set(ac.getReg(), ac));
redisOperations.opsForValue()
.getOperations()
.keys("*")
.forEach(ac -> System.out.println(redisOperations.opsForValue().get(ac)));
}
}
Aircraft.java

I find that book author in this issue says running redis:
https://github.com/mkheck/SpringBootUpAndRunning/issues/1

Related

Spring Batch: Resource must not be null

I am new to spring batch framework. I am making a spring boot program to read from a XML file and store it in the MySQL database.
But the application is throwing the following error.
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:153) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader$$FastClassBySpringCGLIB$$ebb633d0.invoke(<generated>) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.batch.item.xml.StaxEventItemReader$$EnhancerBySpringCGLIB$$1a0f0ba5.open(<generated>) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:205) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:410) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at com.sun.proxy.$Proxy39.run(Unknown Source) ~[na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.execute(JobLauncherApplicationRunner.java:199) ~[spring-boot-autoconfigure-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.executeLocalJobs(JobLauncherApplicationRunner.java:173) ~[spring-boot-autoconfigure-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.launchJobFromProperties(JobLauncherApplicationRunner.java:160) ~[spring-boot-autoconfigure-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:155) ~[spring-boot-autoconfigure-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.run(JobLauncherApplicationRunner.java:150) ~[spring-boot-autoconfigure-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:786) ~[spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776) ~[spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at com.swt.helloworld.HelloworldApplication.main(HelloworldApplication.java:41) ~[classes/:na]
Caused by: java.lang.IllegalArgumentException: The Resource must not be null.
at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.batch.item.xml.StaxEventItemReader.doOpen(StaxEventItemReader.java:205) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
... 43 common frames omitted
I am not able to understand why the resource is null error is coming.I have also attached my BatchConfiguration.java file below:
package com.swt.helloworld.config;
import com.swt.helloworld.model.Product;
import com.swt.helloworld.writer.ConsoleItemWriter;
import com.swt.helloworld.listener.HwJobExecutionListener;
import com.swt.helloworld.listener.HwStepExecutionListener;
import com.swt.helloworld.processor.InMemeItemProcessor;
import com.swt.helloworld.reader.InMemReader;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.LineTokenizer;
import org.springframework.batch.item.xml.StaxEventItemReader;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
#EnableBatchProcessing
#Configuration
public class BatchCondifguration {
#Autowired
private JobBuilderFactory jobs;
#Autowired
private StepBuilderFactory steps;
#Autowired
private HwJobExecutionListener hwJobExecutionListener;
#Autowired
private HwStepExecutionListener hwStepExecutionListener;
#Autowired
private InMemeItemProcessor inMemeItemProcessor;
public Tasklet helloWorldTasklet(){
return (new Tasklet() {
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("Hello world " );
return RepeatStatus.FINISHED;
}
});
}
#Bean
public Step step1(){
return steps.get("step1")
.listener(hwStepExecutionListener)
.tasklet(helloWorldTasklet())
.build();
}
#Bean
public InMemReader reader(){
return new InMemReader();
}
#StepScope
#Bean
public StaxEventItemReader xmlItemReader(
#Value( "#{jobParameters['fileInput']}" )
FileSystemResource inputFile
){
// where to read the xml file
StaxEventItemReader reader = new StaxEventItemReader();
reader.setResource(inputFile);
//need to let reader to know which tags describe the domain object
reader.setFragmentRootElementName("product");
// tell reader how to parse XML and which domain object to be mapped
reader.setUnmarshaller(new Jaxb2Marshaller(){
{
setClassesToBeBound(Product.class);
}
});
return reader;
}
#StepScope
#Bean
public FlatFileItemReader flatFileItemReader(
#Value( "#{jobParameters['fileInput']}" )
FileSystemResource inputFile ){
FlatFileItemReader reader = new FlatFileItemReader();
// step 1 let reader know where is the file
reader.setResource( inputFile );
//create the line Mapper
reader.setLineMapper(
new DefaultLineMapper<Product>(){
{
setLineTokenizer( new DelimitedLineTokenizer() {
{
setNames( new String[]{"prodId","productName","prodDesc","price","unit"});
setDelimiter("|");
}
});
setFieldSetMapper( new BeanWrapperFieldSetMapper<Product>(){
{
setTargetType(Product.class);
}
});
}
}
);
//step 3 tell reader to skip the header
reader.setLinesToSkip(1);
return reader;
}
#Bean
public Step step2(){
return steps.get("step2").
<Integer,Integer>chunk(3)
// .reader(flatFileItemReader( null ))
.reader(xmlItemReader(null))
.writer(new ConsoleItemWriter())
.build();
}
#Bean
public Job helloWorldJob(){
return jobs.get("helloWorldJob")
.incrementer(new RunIdIncrementer())
.listener(hwJobExecutionListener)
.start(step1())
.next(step2())
.build();
}
}
Following the stack trace, I think you need to check your "job parameter" named 'fileInput'. Enter the file path in your program parameter 'fileInput'.
Perhaps it works adding this part in you parameter when you run your batch application:
fileInput=/path/your/input/file
See futher at the Spring document.

PropertyReferenceException No property id found for type UserRegistration

I tried everything from my site but I am not able to solve this issue
last 4 days.
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property id found for type UserRegistration!
I use jpa and springboot in my application, but I don't know why face
this type of issue
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property id found for type UserRegistration!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:90) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:437) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:413) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:366) ~[spring-data-commons-2.5.1.jar:2.5.1]
at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) ~[na:na]
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:348) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:331) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:81) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:249) ~[spring-data-commons-2.5.1.jar:2.5.1]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177) ~[na:na]
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:250) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:383) ~[spring-data-commons-2.5.1.jar:2.5.1]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177) ~[na:na]
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:384) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:95) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:89) ~[spring-data-jpa-2.5.1.jar:2.5.1]
... 70 common frames omitted
I use custom query in my repository file
UserRegistration.kt
package com.userservice.userregistration.entity
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
#Entity
data class UserRegistration(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val userId:Long=-1,
val firstName:String="",
val lastName:String="",
val email:String="",
val departmentId:Long=-1,
)
UserRegistrationRepository.kt
package com.userservice.userregistration.repository
import com.userservice.userregistration.entity.UserRegistration
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
#Repository
interface UserRegistrationRepository : JpaRepository<UserRegistration,Long> {
fun findUserById(userId: Long?): UserRegistration?
}
UserRegistrationService.kt
package com.userservice.userregistration.service
import com.userservice.userregistration.VO.Department
import com.userservice.userregistration.VO.ResponseTemplateVO
import com.userservice.userregistration.entity.UserRegistration
import com.userservice.userregistration.repository.UserRegistrationRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
#Service
class UserRegistrationService {
#Autowired
private lateinit var userRegistrationRepository: UserRegistrationRepository
#Autowired
private lateinit var restTemplate: RestTemplate
fun saveUserDetails(userRegistration: UserRegistration): UserRegistration {
return userRegistrationRepository.save(userRegistration)
}
fun getUserWithDepartment(userId: Long): ResponseTemplateVO {
val vo= ResponseTemplateVO()
val userRegistration:UserRegistration? = userRegistrationRepository.findUserById(userId)
val department: Department? =
restTemplate.getForObject("http://localhost:9001/departments/"+ userRegistration?.departmentId,
Department::class.java)
vo.userRegistration=userRegistration
if (department != null) {
vo.department=department
}
return vo
}
}
UserRegistrationController.kt
package com.userservice.userregistration.controller
import com.userservice.userregistration.VO.ResponseTemplateVO
import com.userservice.userregistration.entity.UserRegistration
import com.userservice.userregistration.service.UserRegistrationService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*
#RestController
#RequestMapping("/users")
class UserRegistrationController {
#Autowired
private lateinit var userRegistrationService: UserRegistrationService
#PostMapping("/")
fun saveUserDetails(#ModelAttribute userRegistration:UserRegistration):UserRegistration{
return userRegistrationService.saveUserDetails(userRegistration)
}
#GetMapping("/{id}")
fun getUserWithDepartment(#PathVariable("id") userId:Long):ResponseTemplateVO{
return userRegistrationService.getUserWithDepartment(userId)
}
}
If I not use custom query on my Repository it show me another issue
"required UserRegistration found Optional" in my
userRegistrationService class
just change
#Repository
interface UserRegistrationRepository : JpaRepository<UserRegistration,Long> {
fun findUserById(userId: Long?): UserRegistration?
}
into
#Repository
interface UserRegistrationRepository : JpaRepository<UserRegistration,Long> {
fun findUserByUserId(userId: Long?): UserRegistration?
}
You don't have to declare separate query method for finding by ID, you can just add #Column annotation for you id property.
#Id
#Column("user_id") // or whatever it's called in the SQL table
#GeneratedValue(strategy = GenerationType.AUTO)
val userId:Long=-1
and then use standard method (Optional<T> findById(ID id);) inherited from JpaRepository
val userRegistration:UserRegistration? =
userRegistrationRepository.findById(userId).orElse(null)

Spring Annotation Object Mapping generic class relationship

I use Spring to store objects from the annotation based Object Mapping in a Neo4j database.
I have a generic class(InformationMutable) which contains as class attribute a list of another class(InformationEntry) of the same generic data type - private List<InformationEntry<T>> entries = new ArrayList<>();.
Full InformationMutable class:
package de.skillkiller.project.entity;
import lombok.*;
import org.springframework.data.neo4j.core.schema.Node;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#EqualsAndHashCode(callSuper = true)
#Node
#Data
#ToString(callSuper = true)
#NoArgsConstructor
#AllArgsConstructor
public class InformationMutable<T extends Serializable> extends Information {
private List<InformationEntry<T>> entries = new ArrayList<>();
public void addEntry(T entry) {
entries.add(new InformationEntry<>(entry));
}
public void removeEntry(InformationEntry<T> entry) {
entries.remove(entry);
}
}
The goal is to have an object where in the list is only objects of the other class but with the same datatype in it. The InformationEntry class extends the datatype with uniform create and update dates.
Other required classes:
InformationEntry:
package de.skillkiller.project.entity;
import lombok.*;
import org.springframework.data.neo4j.core.schema.Node;
import java.io.Serializable;
#EqualsAndHashCode(callSuper = true)
#Node
#Data
#ToString(callSuper = true)
#NoArgsConstructor
#AllArgsConstructor
public class InformationEntry<T extends Serializable> extends BasicNode{
private T entry;
}
Information:
package de.skillkiller.project.entity;
import lombok.*;
import org.springframework.data.neo4j.core.schema.Node;
#EqualsAndHashCode(callSuper = true)
#Node
#Data
#ToString(callSuper = true)
#NoArgsConstructor
#AllArgsConstructor
public abstract class Information extends BasicNode{
private String information;
}
BasicNode:
package de.skillkiller.project.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.support.DateLong;
import java.util.Date;
#Data
#AllArgsConstructor
#NoArgsConstructor
public abstract class BasicNode {
#Id
#GeneratedValue
private Long id;
#DateLong
#LastModifiedDate
private Date changedAt = new Date();
#DateLong
#CreatedDate
private Date enteredAt = new Date();
}
InformationRepository:
package de.skillkiller.project.repository;
import de.skillkiller.project.entity.Information;
import org.springframework.data.neo4j.repository.Neo4jRepository;
public interface InformationRepository extends Neo4jRepository<Information, Long> {
}
Creation Process:
InformationMutable<Integer> informationMutable1 = new InformationMutable<>();
informationMutable1.addEntry(5);
informationMutable1.addEntry(15);
informationMutable1.setInformation("Test");
informationRepository.save(informationMutable1);
If I now create an object from the class InformationMutable, add values to the list and want to save it, I get the following error message:
ava.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:807) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:788) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.4.2.jar:2.4.2]
at de.skillkiller.project.ProjectApplication.main(ProjectApplication.java:19) ~[classes/:na]
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.data.neo4j.core.mapping.Neo4jPersistentEntity.isNew(Object)" because "targetNodeDescription" is null
at org.springframework.data.neo4j.core.Neo4jTemplate.lambda$processNestedRelations$16(Neo4jTemplate.java:495) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:387) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.neo4j.core.Neo4jTemplate.processNestedRelations(Neo4jTemplate.java:452) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.neo4j.core.Neo4jTemplate.lambda$processNestedRelations$16(Neo4jTemplate.java:518) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:387) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.neo4j.core.Neo4jTemplate.processNestedRelations(Neo4jTemplate.java:452) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.neo4j.core.Neo4jTemplate.processRelations(Neo4jTemplate.java:442) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.neo4j.core.Neo4jTemplate.saveImpl(Neo4jTemplate.java:254) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.neo4j.core.Neo4jTemplate.save(Neo4jTemplate.java:225) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save(SimpleNeo4jRepository.java:131) ~[spring-data-neo4j-6.0.3.jar:6.0.3]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:524) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:531) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:156) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.4.3.jar:2.4.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.3.jar:5.3.3]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.3.jar:5.3.3]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.3.jar:5.3.3]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.3.jar:5.3.3]
at com.sun.proxy.$Proxy67.save(Unknown Source) ~[na:na]
at de.skillkiller.project.ProjectApplication.lambda$demo$0(ProjectApplication.java:57) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804) ~[spring-boot-2.4.2.jar:2.4.2]
... 5 common frames omitted
Nevertheless, is it somehow possible with Spring and Neo4j to store such a generic construct and read it out again?
The problem with your setting is that the InformationMutable declares a generic field that is seen by SDN as any other legit #Node annotated entity.
As a consequence SDN wants to create something like
(:Information:InformationMutable) -[:ENTRIES]-> (:InformationEntry) -[:ENTRY] -> (generic entry)
It does not see the generic field as a possible property and it cannot because the definition of the Integer type is done during runtime.
The green nodes on the right side are for example other real #Node entities that you could use and that contain a fixed Integer field, for example.

Spring boot integration testing not working JUnit5

I am trying to do integration testing in spring boot application using JUnit5 but it gives me Null Pointer Exception at that line String response = restTemplate.getForObject("/v1/students", String.class);. All unit tests are working fine but I can't figure out what's wrong with the integration test.
Here is the Integration Test class:
package com.demo.student.demo;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class DemoApplicationTest {
#Autowired
private TestRestTemplate restTemplate;
#Test
public void contextLoads() throws Exception {
String response = restTemplate.getForObject("/v1/students", String.class);
JSONAssert.assertEquals("[{'id':1,'email':'test#test.test'}]", response, false);
}
}
Here is the stacktrace:
java.lang.NullPointerException
at com.demo.student.demo.DemoApplicationTest.contextLoads(DemoApplicationTest.java:18)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:513)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:113)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
And the REST endpoint I am testing against:
package com.demo.student.demo.service;
import com.demo.student.demo.entity.Student;
import com.demo.student.demo.exception.StudentNotFoundException;
import com.demo.student.demo.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class StudentServiceImpl implements StudentService {
private StudentRepository studentRepository;
#Autowired
public StudentServiceImpl(StudentRepository studentRepository){
this.studentRepository = studentRepository;
}
#Override
public List<Student> findAl() {
return studentRepository.findAll();
}
#Override
public Student findById(long id) {
return studentRepository.findById(id).orElseThrow(() -> new StudentNotFoundException(id));
}
#Override
public Student saveOrUpdate(Student student) {
studentRepository.save(student);
return student;
}
#Override
public void deleteById(long id) {
if(this.findById(id) != null)
studentRepository.deleteById(id);
}
}
Oh I forgot to add the plugin for failsafe in the pom.xml. And add the #ExtendWith(SpringExtension.class) at the class level. My bad!

Testing spring mvc controller having the view with tiles configuration

I dont know how to test a controller that has view with tiles configuration.
Below is the unit test case written
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/servlet-context.xml", "file:src/main/webapp/WEB-INF/tiles-definitions.xml"})
#TestExecutionListeners(DependencyInjectionTestExecutionListener.class)
public class BankControllerTest {
#Inject
private ApplicationContext applicationContext;
private HandlerAdapter handlerAdapter;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private BankController controller;
private ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final HandlerMapping handlerMapping = applicationContext.getBean(HandlerMapping.class);
final HandlerExecutionChain handler = handlerMapping.getHandler(request);
Assert.assertNotNull("No handler found for request, check you request mapping", handler);
final Object controller = handler.getHandler();
for (final HandlerInterceptor interceptor : handlerMapping.getHandler(request).getInterceptors()) {
if (!interceptor.preHandle(request, response, controller)) {
return null;
}
}
return handlerAdapter.handle(request, response, controller);
}
#Before
public void setUp() throws Exception {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
this.handlerAdapter = applicationContext.getBean(HandlerAdapter.class);
}
#Test
public void banksList() throws Exception {
request.setRequestURI("/banksList.do");
request.setMethod("GET");
final ModelAndView mav = handle(request, response);
// assertViewName(mav, "banksList");
// assertAndReturnModelAttributeOfType(mav, "banksList",
// BankList.class);
}
}
I get the following error
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/sach-context.xml]
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/tiles-definitions.xml]
ERROR: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#2c1e6b] to prepare test instance [com.myapp.simulator.controller.BankControllerTest#811c88]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from URL [file:src/main/webapp/WEB-INF/tiles-definitions.xml]; nested exception is java.net.UnknownHostException: tiles.apache.org
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:408)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:81)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
... 24 more
Caused by: java.net.UnknownHostException: tiles.apache.org
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
... 34 more
How to overcome this error. What is the testing approach for controller. do i need to use any other framework in order to write testcases for my controllers
Put the lazy-init="true" for tiles bean configuration as below.
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" lazy-init="true"
It depends on what you want to test. If you are just making sure that the tile view names are correct, then it is correct you don't have to use Spring Configuration. However if you want to see if a view is resolved or check model attributes, responses, etc then Spring has a MVC testing framework. It was a standalone, but it is now part of 3.2. So if you are using Spring 3 you might want to look at the tests in SpringMVC Showcase. I haven't tested it yet with Tiles, but it does have the ability to set a view resolver so it should be possible.
The problem is that you can not load a spring context with beans that requires an web container.
If you only want to test the controllers, then I recommend real Unit test, without Spring Context. That mean you need to create mocks for the classes that are required by your controller.
I am using the following to load test cases in spring boot with tiles as an example
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {MyApplication.class, TestConfigurtaion.class})
#WebAppConfiguration
public class UserRepositoryTest {
#Autowired
UserRepository userRepository;
#Test
public void testCase{
}
}
Then another class for tiles configuration
#Configuration
public class TestConfigurtaion {
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[] { "file:src/main/webapp/WEB-INF/views/tiles.xml" });
configurer.setCheckRefresh(true);
return configurer;
}
}

Resources