java.lang.ClassCastException: java.util.HashMap cannot be cast to com.spacestudy.model.Investigator - spring-data-jpa

I am trying to write test case for Repository method. In that Test case I want to test Investigator name using assertEquals(). Return type of method is set for that I use for each loop to retrieve result from set and then checked expected and actual result using assertEquals() but I am getting java.lang.ClassCastException: java.util.HashMap cannot be cast to com.spacestudy.model.Investigator
can any one please tell me what I am doing wrong in test case?
InvestigatorRepository
#Query("select new map(invest.sInvestigatorName as sInvestigatorName)"
+ " from Investigator invest")
Set<Investigator> findSinvestigatorName();
I tried Like this
#RunWith(SpringRunner.class)
#DataJpaTest
public class TestInvestigatorRepository {
#Autowired
public TestEntityManager testEm;
#Autowired
InvestigatorRepository investRepo;
#Test
public void testFindSinvestigatorName() {
Investigator invest = new Investigator();
invest.setsInvestigatorName("abc");
invest.setnInstId(60);
Investigator saveInDb = testEm.merge(invest);
Set<Investigator> getFromDb = investRepo.findSinvestigatorName();
for(Investigator result : getFromDb) {
assertEquals(saveInDb.getsInvestigatorName(),result.sInvestigatorName);
}
}
}
Stack Trace
java.lang.ClassCastException: java.util.HashMap cannot be cast to com.spacestudy.model.Investigator
at com.spacestudy.repository.TestInvestigatorRepository.testFindSinvestigatorName(TestInvestigatorRepository.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
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:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

The HQL query you specify explicitly returns a Map, but the return type specified for the method specifies Set<Investigator> which are incompatible types, hence the error.
Spring Data tries to convert the types but fails and in the end, just tries to cast the result to the desired type.
In order to fix this you need to use compatible types options are:
let your query return Investigators.
let your query return a tuple by just listing the attributes: select invest.sInvestigatorName as sInvestigatorName from Investigator invest. Spring Data should be able to map that to an Investigator although your "interesting" property names might cause some troubles.
Since you are really just return a single attribute you might as well make the method return a Set<String> and use the query given in the previous point.

Related

Why my unit test is giving me an AssertionFailedError when I try to render another page

I am learning unit testing and trying to check if the login is valid on the HomePage and if so that the SuccessPage is rendered but it is giving me an AssertionFailedError
.java:
#Test
public void validLogin(){
tester.startPage(HomePage.class);
FormTester form = tester.newFormTester("userForm");
form.setValue("username", "emile");
form.setValue("password", "123");
form.submit();
//onsubmit the Successpage is rendered in response
tester.assertRenderedPage(SuccessPage.class);
}
the error:
[main] INFO org.apache.wicket.Application - [WicketTesterApplication-768a67f4-8bf1-45d0-bdcb-3a9be18172e1] init: Wicket core library initializer
[main] INFO org.apache.wicket.Application - [WicketTesterApplication-768a67f4-8bf1-45d0-bdcb-3a9be18172e1] init: Wicket extensions initializer
[main] INFO org.apache.wicket.Application - [WicketTesterApplication-768a67f4-8bf1-45d0-bdcb-3a9be18172e1] init: Wicket jQuery UI initializer
[main] INFO org.apache.wicket.Application - [WicketTesterApplication-768a67f4-8bf1-45d0-bdcb-3a9be18172e1] init: Wicket jQuery UI initializer (theme-uilightness)
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
junit.framework.AssertionFailedError: classes not the same, expected 'class com.mycompany.SuccessPage', current 'class com.mycompany.HomePage'
at org.apache.wicket.util.tester.WicketTester.assertResult(WicketTester.java:798)
at org.apache.wicket.util.tester.WicketTester.assertRenderedPage(WicketTester.java:697)
at com.mycompany.TestHomePage.validLogin(TestHomePage.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
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)
I got the answer, so I didn't reference the form.submit(); to the onSubmit() function so I basically did this:
#Test
public void validLogin() throws Exception {
tester.startPage(HomePage.class);
// tester.startComponentInPage(HomePage.class);
FormTester form = tester.newFormTester("userForm");
form.setValue("username", "emile");
form.setValue("password", "123");
form.submit("error"); // new code that was edited
//onsubmit the Successpage is rendered in response
tester.assertRenderedPage(SuccessPage.class);
}
the form.submit("error"); now references to the wicket:id="error" and passed the test :D

Controller Test fails with MethodArgumentConversionNotSupportedException but not in the running application

Spring Boot App using 2.0.3.RELEASE of Spring Boot.
So I have REST API controller written like this:
#RestController
#RequestMapping("/root/{id}")
#Slf4j
public class RootController {
#GetMapping
public ResponseEntity<?> getXXX(
#PathVariable String id,
#RequestParam(value = "status") Status status,
#RequestParam(value = "comment") String comment,
#RequestParam(value = "other") Optional<String> other) {
log.info("Requested getXXX id={} status={} other={} comment={}", id, status, other, comment);
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
}
So the interesting part is the Optional<String> other on the above definition. I have tested the above manually via calling curl:
curl -v -X GET 'http://localhost:8080/root/ID?status=OK&comment=Comment'
which results in logging output on console like this:
...Requested getXXX id=ID status=OK other=Optional.empty comment=Comment
and using curl like this:
curl -v -X GET 'http://localhost:8080/root/ID?status=OK&comment=Comment&other=MoreOther'
which results in the following output:
Requested getXXX id=ID status=OK other=Optional[MoreOther] comment=Comment
So far so good.
But of course I would like to check this via unit tests and not manually...So I wrote a REST controller test which looks like this:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = RootController.class)
#AutoConfigureMockMvc
public class RootControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void shouldReturnNotImplemented() throws Exception {
//#formatter:off
mvc.perform(
get("/root/xyz?status={status}&comment={comment}&other={other}", Status.NOTOK, "COMMENT", Optional.<String>of("Other"))
.characterEncoding("UTF-8")
.accept(MediaType.ALL)
)
.andExpect(
status().isNotImplemented()
);
//#formatter:on
}
But unfortunately the above test fails with:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /root/xyz
Parameters = {status=[OK], comment=[Comment], other=[Optional[Other]]}
Headers = {Accept=[*/*]}
Body = null
Session Attrs = {}
Handler:
Type = ...RootController
Method = public org.springframework.http.ResponseEntity<?> .getRoot(java.lang.String,Status,java.lang.String,java.util.Optional<java.lang.String>)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 500
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Where the exception: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException is the thing I don't understand.
The final question is: Why does the test fail but the running application does not? Does someone has a hint / idea for me?
Update 1:
I have tested also the following:
get("/root/xyz?status={status}&comment={comment}&other={other}", Status.NOTOK, "COMMENT", "Other")
and furthermore which means using only strings.
get("/root/xyz?status={status}&comment={comment}&other={other}", "NOTOK", "COMMENT", "Other")
The point that the running application works perfectly but unfortunately the test do not.
Update 2:
So after turning on debugging mode in test I got the following output: This brings me more and more into the direction that there is a bug within it..cause the parameters are always converted into String instead of Optional...and based on the parameters of get(..., Object... uriVars)
it looks like there is some problem in the code...
2018-07-16 15:50:21.029 DEBUG 16022 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /root/xyz
2018-07-16 15:50:21.031 DEBUG 16022 --- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<?> de....RootController.getXXX(java.lang.String,de....Status,java.lang.String,java.util.Optional<java.lang.String>)]
2018-07-16 15:50:21.057 DEBUG 16022 --- [main] .w.s.m.m.a.ServletInvocableHandlerMethod : Failed to resolve argument 3 of type 'java.util.Optional'
org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Optional'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Optional': no matching editors or conversion strategy found
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:127)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:166)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:165)
at de...RootControllerTest.shouldReturnNotImplemented(RootControllerTest.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
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:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Optional': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:99)
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:73)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:52)
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:692)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:123)
... 50 common frames omitted
This is an issue with how you are loading the test up.
When you specify #SpringBootTest(classes = RootController.class) a class with SpringBootTest it will only load that class into the context i.e. it allows you to specify certain configurations etc. that you would want to test for some integration tests rather than using ContextConfiguration.
You can either remove the RootController and load a full test application context, effectively loading your entire application.
or just specify,
#RunWith(SpringRunner.class)
#WebMvcTest
public class RootControllerTest {
To load a slice test, which will only load the required beans to completely test the WebMVC.
working tests,
https://github.com/Flaw101/mockmvctests
Edit,
I've updated my example and introduced a second controller but only load the RootController in the RootControllerMock via #WebMvcTest(controllers = RootController.class). You can see in the logged output that it only load this controller.
2018-07-16 15:34:28.264 INFO 6176 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/root/{id}],methods=[GET]}" onto public org.springframework.http.ResponseEntity<?> com.darrenforsythe.mockmvc.RootController.getXXX(java.lang.String,java.lang.String,java.lang.String,java.util.Optional<java.lang.String>)
references,
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests

Getting error when querying the audit table using haschanged

I have Template entity which has:
#ManyToOne
#JsonView(JsonDefinitionMapper.SecondLevel.class)
#Audited
private TemplateType templateType;
instance.
When I am going to query the all the changes using loop through entity properties as below (properties are get by metadata of entity) :
for(String property:PropertiesList){
newValue = auditReader.createQuery()
.forRevisionsOfEntity(Template.class, false, true)
.addProjection(AuditEntity.property(property))
.add(AuditEntity.property(property).hasChanged())
.add(AuditEntity.id().eq(templateId))
.add(AuditEntity.revisionNumber().eq(revisionNumber)).getSingleResult();
}
the generated Template_AUD table has template_type_mod,template_type_id columns(Auto generated)
I am getting this error when running above query:
org.hibernate.QueryException: could not resolve property: templateType of: com.templates.domain.Template_AUD [select e__.templateType from com.templates.domain.Template_AUD e__, com.template.domain.AuditedRevisionEntity r where e__.templateType_MOD = :_p0 and e__.originalId.id = :_p1 and e__.originalId.REV.id = :_p2 and e__.originalId.REV.id = r.id]
at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:218)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:76)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894)
at org.hibernate.envers.internal.tools.query.QueryBuilder.toQuery(QueryBuilder.java:226)
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildQuery(AbstractAuditQuery.java:79)
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildAndExecuteQuery(AbstractAuditQuery.java:85)
at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.list(RevisionsOfEntityQuery.java:108)
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:97)
at com.template.dataRepository.TemplateRevisionRepository.getAllChangedPropertiesWithREvisions(TemplateRevisionRepository.java:211)
at com.template.dataRepository.TemplateRevisionRepository$$FastClassBySpringCGLIB$$5bf5efd1.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at com.template.dataRepository.TemplateRevisionRepository$$EnhancerBySpringCGLIB$$952a9450.getAllChangedPropertiesWithREvisions()
at com.template.EnversTest.getAllChangedPropertiesWithREvisions(EnversTest.java:151)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
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:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
i am using postgres database
My initial idea was to leverage the new relation traversal API added in Envers 5.2 by which you would have written your query much like the following:
final List results = auditReader.createQuery()
.forEntitiesModifiedAtRevision( Template.class, revNo )
.traverseRelation( "templateType", JoinType.INNER )
.addProjection( AuditEntity.selectEntity( false ) )
.up()
.add( AuditEntity.property( "templateType" ).hasChanged() )
.getResultList();
The idea here is that we'd basically request that the TemplateType be returned in the resulting list but only if it was deemed modified on the root entity, Template; however, this query introduces what I believe is a bug:
org.hibernate.QueryException: Named parameter [revision] not set
This is because the subquery added to the root query specifies a named parameter revision; however, the query logic never binds the revision value; leading to this problem.
I've filed issue HHH-11981 to address this problem.
So for now, the only suggestion I have is if your entity class has anything beyond basic type properties, you'll likely need to resort to using reflection in your code to actually obtain the values from the returned bean
final List results = auditReader.createQuery()
.forEntitiesModifiedAtRevision( Template.class, revNo )
.add( AuditEntity.property( propertyName ).hasChanged() )
.getResultList();
For the entry in the list, you'd need to use reflection to call the appropriate getter for the appropriate property identified by propertyName. It is less than ideal but at least circumvents the query problems you're facing.

How to use OAuth2RestTemplate + Spring 4?

I'm trying to understand how to use a OAuth2RestTemplate object to consume my OAuth2 secured REST service (which is running under a different project and let's assume also on a different server etc...)
f.e. my rest service is:
https://localhost:8443/rest/api/user
-> Accessing this URL generates an error as I am not authenticated
To request a token I would go to:
https://localhost:8443/rest/oauth/token?grant_type=password&client_id=test&client_secret=test&username=USERNAME&password=PASSWORD
After I receive the token I can then connect to the REST API by using the following URL (example token inserted)
https://localhost:8443/rest/api/user?access_token=06
I currently tried something with the following objects:
#EnableOAuth2Client
#Configuration
class MyConfig {
#Value("${oauth.resource:https://localhost:8443}")
private String baseUrl;
#Value("${oauth.authorize:https://localhost:8443/rest/oauth/authorize}")
private String authorizeUrl;
#Value("${oauth.token:https://localhost:8443/rest/oauth/token}")
private String tokenUrl;
#Bean
protected OAuth2ProtectedResourceDetails resource() {
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
List scopes = new ArrayList<String>(2);
scopes.add("write");
scopes.add("read");
resource.setAccessTokenUri(tokenUrl);
resource.setClientId("test");
resource.setClientSecret("test");
resource.setGrantType("password");
resource.setScope(scopes);
resource.setUsername("test");
resource.setPassword("test");
return resource;
}
#Bean
public OAuth2RestOperations restTemplate() {
CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
AccessTokenRequest atr = new DefaultAccessTokenRequest();
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider();
provider.setRequestFactory(requestFactory);
restTemplate.setAccessTokenProvider(provider);
return restTemplate;
}
}
I am tried to get token in controller like below.
#Controller
public class TestController {
#Autowired
private OAuth2RestOperations restTemplate;
#RequestMapping(value="/", method= RequestMethod.GET)
public String TestForm() {
System.out.println("Token : " + restTemplate.getAccessToken().getValue());
}
}
But i got below exception
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/web] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails cannot be cast to org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails] with root cause
java.lang.ClassCastException: org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails cannot be cast to org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:190)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at com.divyshivglobalinvestor.web.controller.PersonalLoanController.PersonalLoanForm(PersonalLoanController.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
at org.apache.coyote.AreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:722)bstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.Th
From some blog I found that, if we need to grant password then, instead of ResourceOwnerPasswordResourceDetails, it should be used AccessTokenRequest (which is a Map and is ephemeral). It would be great if someone can help me in getting accessToken. :)
Thanks in advance !
You should use ResourceOwnerPasswordAccessTokenProvider instead of AuthorizationCodeAccessTokenProvider in restTemplate bean

I have to write JUnit test case for service layer which uses ListIterator and returns list

Problem:
I have service method which returns list of objects in reverse order.
It is fetching list of objects from MongoDB using MongoTemplate,Query and uses ListIterator for reversing the list.
Now, I have to write JUnit test case for the above.
My present code where I am Mocking mongotemplate
MongoTemplate mongoTemplate = Mockito.mock(MongoTemplate.class);
Query query = Mockito.mock(Query.class);
CRDetails crDetails = new CRDetails();
CertificateGuidelines certG1 = new CertificateGuidelines("certG1", Constants.CERTIFICATION_TEAM, Constants.DOC_DEVELOPER_STATUS, 1);
CertificateGuidelines certG2 = new CertificateGuidelines("certG2", Constants.DOCDEVELOPER, Constants.CERT_TEAM_STATUS, 2);
CertificateGuidelines certG3 = new CertificateGuidelines("certG3", Constants.CERTIFICATION_TEAM, Constants.DOC_DEVELOPER_STATUS, 3);
List<CertificateGuidelines> newHistoryList = new ArrayList<CertificateGuidelines>();
newHistoryList.add(certG1);
newHistoryList.add(certG2);
newHistoryList.add(certG3);
Mockito.when(mongoTemplate.findOne((org.springframework.data.mongodb.core.query.Query) Matchers.any(Query.class), Matchers.any(Class.class))).thenReturn(crDetails);
CRService service = new CRService();
service.setCertMongoTemplate(mongoTemplate);
assertEquals(historyList, newHistoryList);
My service method:
public List<CertificateGuidelines> getHistoryForCertGuidelines(String crNum) {
Query query = new Query(Criteria.where("cr").is(crNum));
CRDetails details = certMongoTemplate.findOne(query, CRDetails.class,
Constants.COLLECTION_NAME);
logger.debug("in history");
if (details != null) {
logger.debug("Certification Guidelines has " + details.getCertGuidelinesList().size() + "previous updates");
}
List<CertificateGuidelines> historyList = new ArrayList<CertificateGuidelines>();
// Add objects to list.
// Generate an iterator. Start just after the last CG object.
ListIterator<CertificateGuidelines> listItr = details.getCertGuidelinesList().listIterator(
details.getCertGuidelinesList().size());
// Iterate in reverse.
while (listItr.hasPrevious()) {
historyList.add((CertificateGuidelines) listItr.previous());
}
return historyList;
}
I know I am doing some mistake in writing test case. Not clear on how to approach. Please Guide.
Error Trace
java.lang.AssertionError: expected:<historyList> but was:<[com.cerner.docworks.domain.CertificateGuidelines#13805618, com.cerner.docworks.domain.CertificateGuidelines#56ef9176, com.cerner.docworks.domain.CertificateGuidelines#4566e5bd]>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
at com.cerner.docworks.service.test.CRServiceTest.testServiceHistoryDB(CRServiceTest.java:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
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:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Thanks in advance
I believe that you are testing the equality of two lists, when what you really want to do is check that the lists contain the same elements.
The easiest way to do this is to use Hamcrest, which has the added advantage that it will show a better message in the event of failure.
Assert.assertThat(historyList,IsIterableContainingOrder.contains(newHistoryList.toArray()));