[英]Spring HATEOAS RepresentationModel, Cannot set property links because no setter, no wither and it's not part of the persistence constructor
GOAL : I'm just trying to invoke a get call on REST endpoint of a Spring HATEOAS application.目标:我只是想在 Spring HATEOAS 应用程序的 REST 端点上调用 get 调用。 This is a simple project with MongoDB as the database.这是一个以MongoDB为数据库的简单项目。
Expected Result: When I try to invoke Get endpoint from the REST controller class, appropriate response should be return.预期结果:当我尝试从 REST 控制器类调用 Get 端点时,应该返回适当的响应。
Actual Result: cannot invoke Get endpoint, giving me an internal server error when invoking using the postman.实际结果:无法调用 Get 端点,使用邮递员调用时出现内部服务器错误。
below is the REST endpoint I'm trying to invoke下面是我试图调用的 REST 端点
localhost:8086/api/customers
below is the error response下面是错误响应
{
"timestamp": "2020-09-01T17:34:28.779+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/api/customers"
}
What I've tried: Basically My Spring boot application trying to do the CRUD operations of Customer and order functionality.我尝试过的:基本上我的 Spring 启动应用程序尝试执行客户和订单功能的 CRUD 操作。 initilaly I've preloaded some sample data to the mongodb database.最初,我已将一些示例数据预加载到 mongodb 数据库中。 When I ran the application I can see all the data from the MongoDB compass.当我运行应用程序时,我可以看到来自 MongoDB 指南针的所有数据。 My app starts without any errors.我的应用程序启动时没有任何错误。 But when I tried to invoke any REST endpoint then it gives me an error.但是当我尝试调用任何 REST 端点时,它给了我一个错误。
below is the complete stacktrace.下面是完整的堆栈跟踪。
2020-09-01 23:03:11.446 INFO 15824 --- [ main] com.devzigma.DemoApplication : Starting DemoApplication on SLL014289 with PID 15824 (D:\Java-excersie\spring-hateoas-baeldung - with mongo\target\classes started by buddhika_jayakodi in D:\Java-excersie\spring-hateoas-baeldung - with mongo)
2020-09-01 23:03:11.449 INFO 15824 --- [ main] com.devzigma.DemoApplication : No active profile set, falling back to default profiles: default
2020-09-01 23:03:12.192 INFO 15824 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
2020-09-01 23:03:12.288 INFO 15824 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 91ms. Found 2 MongoDB repository interfaces.
2020-09-01 23:03:12.994 INFO 15824 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8086 (http)
2020-09-01 23:03:13.005 INFO 15824 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-09-01 23:03:13.005 INFO 15824 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-09-01 23:03:13.177 INFO 15824 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-09-01 23:03:13.177 INFO 15824 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1650 ms
2020-09-01 23:03:13.320 INFO 15824 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2020-09-01 23:03:13.371 INFO 15824 --- [localhost:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:164}] to localhost:27017
2020-09-01 23:03:13.375 INFO 15824 --- [localhost:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=9, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=2701575}
2020-09-01 23:03:14.086 INFO 15824 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-09-01 23:03:14.287 INFO 15824 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8086 (http) with context path ''
2020-09-01 23:03:14.298 INFO 15824 --- [ main] com.devzigma.DemoApplication : Started DemoApplication in 3.483 seconds (JVM running for 4.443)
2020-09-01 23:03:14.338 INFO 15824 --- [ main] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:165}] to localhost:27017
2020-09-01 23:04:28.673 INFO 15824 --- [nio-8086-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-09-01 23:04:28.673 INFO 15824 --- [nio-8086-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-09-01 23:04:28.677 INFO 15824 --- [nio-8086-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
2020-09-01 23:04:28.754 ERROR 15824 --- [nio-8086-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Cannot set property links because no setter, no wither and it's not part of the persistence constructor public com.devzigma.model.Order()!] with root cause
java.lang.IllegalStateException: Cannot set property links because no setter, no wither and it's not part of the persistence constructor public com.devzigma.model.Order()!
at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:118) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:63) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:450) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:367) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:347) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:317) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readMap(MappingMongoConverter.java:1187) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:288) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1580) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1478) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:450) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:367) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:347) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:317) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:250) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:246) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:98) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3141) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2788) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2518) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2500) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:856) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:383) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:205) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:55) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_221]
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:549) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.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.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.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.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.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.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at com.sun.proxy.$Proxy60.findAll(Unknown Source) ~[na:na]
at com.devzigma.services.CustomerServiceImpl.allCustomers(CustomerServiceImpl.java:24) ~[classes/:na]
at com.devzigma.controller.CustomerController.getAll(CustomerController.java:38) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_221]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.37.jar:9.0.37]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_221]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_221]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.37.jar:9.0.37]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]
below is the CustomerController
class.下面是CustomerController
类。
package com.devzigma.controller;
import com.devzigma.model.Customer;
import com.devzigma.model.Order;
import com.devzigma.services.CustomerService;
import com.devzigma.services.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.Link;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Optional;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@RestController
@RequestMapping("/api")
public class CustomerController {
@Autowired
private CustomerService customerService;
@Autowired
private OrderService orderService;
@GetMapping(value = "/customers/{customerId}")
public Optional<Customer> getCustomerById(@PathVariable String customerId) {
return customerService.getCustomerDetail(customerId);
}
@GetMapping(value = "/customers")
public List<Customer> getAll() {
return customerService.allCustomers();
}
}
below are the Customer
and Order
classes of model package下面是模型包的Customer
和Order
类
Customer.java class Customer.java 类
package com.devzigma.model;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.hateoas.RepresentationModel;
import java.util.Map;
@Document
public class Customer extends RepresentationModel<Customer> {
private String customerId;
private String customerName;
private String companyName;
private Map<String, Order> orders;
public Customer() {
}
public Customer(String customerId, String customerName, String companyName) {
this.customerId = customerId;
this.customerName = customerName;
this.companyName = companyName;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Map<String, Order> getOrders() {
return orders;
}
public void setOrders(final Map<String, Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Customer{" +
"customerId='" + customerId + '\'' +
", customerName='" + customerName + '\'' +
", companyName='" + companyName + '\'' +
", orders=" + orders +
'}';
}
}
then the Order.java class然后是 Order.java 类
package com.devzigma.model;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.hateoas.RepresentationModel;
@Document
public class Order extends RepresentationModel<Order> {
private String orderId;
private double price;
private int quantity;
public Order() {
}
public Order(String orderId, double price, int quantity) {
this.orderId = orderId;
this.price = price;
this.quantity = quantity;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@Override
public String toString() {
return "Order{" +
"orderId='" + orderId + '\'' +
", price=" + price +
", quantity=" + quantity +
'}';
}
}
below are the two repository interfaces which extends MongoRepository<>下面是扩展 MongoRepository<> 的两个存储库接口
CustomerRepository客户资料库
package com.devzigma.repository;
import com.devzigma.model.Customer;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface CustomerRepository extends MongoRepository<Customer, String> {
}
OrderRepository订单库
package com.devzigma.repository;
import com.devzigma.model.Order;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface OrderRepository extends MongoRepository<Order, String> {
}
In the services package I have CustomerService and OrderService interfaces with their respective implementations.在服务包中,我有 CustomerService 和 OrderService 接口以及它们各自的实现。
CustomerService and it's implementation CustomerService及其实现
package com.devzigma.services;
import com.devzigma.model.Customer;
import java.util.List;
import java.util.Optional;
public interface CustomerService {
Optional<Customer> getCustomerDetail(String id);
List<Customer> allCustomers();
}
package com.devzigma.services;
import com.devzigma.model.Customer;
import com.devzigma.repository.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerRepository customerRepository;
@Override
public Optional<Customer> getCustomerDetail(String id) {
return customerRepository.findById(id);
}
@Override
public List<Customer> allCustomers() {
return customerRepository.findAll();
}
}
then the OrderService with it's implementation然后是 OrderService 及其实现
package com.devzigma.services;
import com.devzigma.model.Order;
import java.util.Optional;
public interface OrderService {
Optional<Order> getAllOrdersForCustomer(String customerId);
}
package com.devzigma.services;
import com.devzigma.model.Order;
import com.devzigma.repository.CustomerRepository;
import com.devzigma.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private OrderRepository orderRepository;
@Override
public Optional<Order> getAllOrdersForCustomer(String customerId) {
return orderRepository.findById(customerId);
}
}
In my main class I have implements the CommandLineRunner so that I can populate MongoDB database with sample data.在我的主类中,我实现了 CommandLineRunner,以便我可以用示例数据填充 MongoDB 数据库。
below is the main class.下面是主类。
package com.devzigma;
import com.devzigma.model.Customer;
import com.devzigma.model.Order;
import com.devzigma.repository.CustomerRepository;
import com.devzigma.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.HashMap;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private OrderRepository orderRepository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
customerRepository.deleteAll();
orderRepository.deleteAll();
final Customer customer1 = new Customer("10A", "Jane", "ABC Company");
final Customer customer2 = new Customer("20B", "Bob", "XYZ Company");
final Customer customer3 = new Customer("30C", "Tim", "CKV Company");
HashMap<String, Order> cus1order = new HashMap<>();
cus1order.put("001A", new Order("001A", 150.00, 25));
cus1order.put("002A", new Order("002A", 250.00, 15));
customer1.setOrders(cus1order);
customerRepository.save(customer1);
customerRepository.save(customer2);
customerRepository.save(customer3);
}
}
finally , below is my application.properties file最后,下面是我的 application.properties 文件
server.port=8086
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.uri=mongodb://localhost:27017/customer-order
I know this is lot of boilerplate code.我知道这是很多样板代码。 but please bear with me.但请耐心等待。 If can anyone give my insight how to fix above error which was given as the stacktrace, then it would be much appreciated.如果有人能告诉我如何解决作为堆栈跟踪给出的上述错误,那么将不胜感激。
Good day!再会!
GOAL : I'm just trying to invoke a get call on REST endpoint of a Spring HATEOAS application.目标:我只是想在 Spring HATEOAS 应用程序的 REST 端点上调用 get 调用。 This is a simple project with MongoDB as the database.这是一个以MongoDB为数据库的简单项目。
Expected Result: When I try to invoke Get endpoint from the REST controller class, appropriate response should be return.预期结果:当我尝试从 REST 控制器类调用 Get 端点时,应该返回适当的响应。
Actual Result: cannot invoke Get endpoint, giving me an internal server error when invoking using the postman.实际结果:无法调用 Get 端点,使用邮递员调用时出现内部服务器错误。
below is the REST endpoint I'm trying to invoke下面是我试图调用的 REST 端点
localhost:8086/api/customers
below is the error response下面是错误响应
{
"timestamp": "2020-09-01T17:34:28.779+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/api/customers"
}
What I've tried: Basically My Spring boot application trying to do the CRUD operations of Customer and order functionality.我尝试过的:基本上我的 Spring 启动应用程序试图执行客户和订单功能的 CRUD 操作。 initilaly I've preloaded some sample data to the mongodb database.最初,我已将一些示例数据预加载到 mongodb 数据库中。 When I ran the application I can see all the data from the MongoDB compass.当我运行应用程序时,我可以看到来自 MongoDB 指南针的所有数据。 My app starts without any errors.我的应用程序启动时没有任何错误。 But when I tried to invoke any REST endpoint then it gives me an error.但是当我尝试调用任何 REST 端点时,它给了我一个错误。
below is the complete stacktrace.下面是完整的堆栈跟踪。
2020-09-01 23:03:11.446 INFO 15824 --- [ main] com.devzigma.DemoApplication : Starting DemoApplication on SLL014289 with PID 15824 (D:\Java-excersie\spring-hateoas-baeldung - with mongo\target\classes started by buddhika_jayakodi in D:\Java-excersie\spring-hateoas-baeldung - with mongo)
2020-09-01 23:03:11.449 INFO 15824 --- [ main] com.devzigma.DemoApplication : No active profile set, falling back to default profiles: default
2020-09-01 23:03:12.192 INFO 15824 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
2020-09-01 23:03:12.288 INFO 15824 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 91ms. Found 2 MongoDB repository interfaces.
2020-09-01 23:03:12.994 INFO 15824 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8086 (http)
2020-09-01 23:03:13.005 INFO 15824 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-09-01 23:03:13.005 INFO 15824 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-09-01 23:03:13.177 INFO 15824 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-09-01 23:03:13.177 INFO 15824 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1650 ms
2020-09-01 23:03:13.320 INFO 15824 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2020-09-01 23:03:13.371 INFO 15824 --- [localhost:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:164}] to localhost:27017
2020-09-01 23:03:13.375 INFO 15824 --- [localhost:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=9, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=2701575}
2020-09-01 23:03:14.086 INFO 15824 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-09-01 23:03:14.287 INFO 15824 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8086 (http) with context path ''
2020-09-01 23:03:14.298 INFO 15824 --- [ main] com.devzigma.DemoApplication : Started DemoApplication in 3.483 seconds (JVM running for 4.443)
2020-09-01 23:03:14.338 INFO 15824 --- [ main] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:165}] to localhost:27017
2020-09-01 23:04:28.673 INFO 15824 --- [nio-8086-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-09-01 23:04:28.673 INFO 15824 --- [nio-8086-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-09-01 23:04:28.677 INFO 15824 --- [nio-8086-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
2020-09-01 23:04:28.754 ERROR 15824 --- [nio-8086-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Cannot set property links because no setter, no wither and it's not part of the persistence constructor public com.devzigma.model.Order()!] with root cause
java.lang.IllegalStateException: Cannot set property links because no setter, no wither and it's not part of the persistence constructor public com.devzigma.model.Order()!
at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:118) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:63) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:450) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:367) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:347) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:317) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readMap(MappingMongoConverter.java:1187) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:288) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1580) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1478) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:450) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:367) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:347) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:317) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:250) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:246) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:98) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3141) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2788) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2518) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2500) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:856) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:383) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:205) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:55) ~[spring-data-mongodb-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_221]
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:549) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.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.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.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.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.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.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at com.sun.proxy.$Proxy60.findAll(Unknown Source) ~[na:na]
at com.devzigma.services.CustomerServiceImpl.allCustomers(CustomerServiceImpl.java:24) ~[classes/:na]
at com.devzigma.controller.CustomerController.getAll(CustomerController.java:38) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_221]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) [tomcat-embed-core-9.0.37.jar:9.0.37]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.37.jar:9.0.37]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_221]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_221]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.37.jar:9.0.37]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]
below is the CustomerController
class.下面是CustomerController
类。
package com.devzigma.controller;
import com.devzigma.model.Customer;
import com.devzigma.model.Order;
import com.devzigma.services.CustomerService;
import com.devzigma.services.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.Link;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Optional;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@RestController
@RequestMapping("/api")
public class CustomerController {
@Autowired
private CustomerService customerService;
@Autowired
private OrderService orderService;
@GetMapping(value = "/customers/{customerId}")
public Optional<Customer> getCustomerById(@PathVariable String customerId) {
return customerService.getCustomerDetail(customerId);
}
@GetMapping(value = "/customers")
public List<Customer> getAll() {
return customerService.allCustomers();
}
}
below are the Customer
and Order
classes of model package下面是模型包的Customer
和Order
类
Customer.java class Customer.java 类
package com.devzigma.model;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.hateoas.RepresentationModel;
import java.util.Map;
@Document
public class Customer extends RepresentationModel<Customer> {
private String customerId;
private String customerName;
private String companyName;
private Map<String, Order> orders;
public Customer() {
}
public Customer(String customerId, String customerName, String companyName) {
this.customerId = customerId;
this.customerName = customerName;
this.companyName = companyName;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Map<String, Order> getOrders() {
return orders;
}
public void setOrders(final Map<String, Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Customer{" +
"customerId='" + customerId + '\'' +
", customerName='" + customerName + '\'' +
", companyName='" + companyName + '\'' +
", orders=" + orders +
'}';
}
}
then the Order.java class然后是 Order.java 类
package com.devzigma.model;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.hateoas.RepresentationModel;
@Document
public class Order extends RepresentationModel<Order> {
private String orderId;
private double price;
private int quantity;
public Order() {
}
public Order(String orderId, double price, int quantity) {
this.orderId = orderId;
this.price = price;
this.quantity = quantity;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@Override
public String toString() {
return "Order{" +
"orderId='" + orderId + '\'' +
", price=" + price +
", quantity=" + quantity +
'}';
}
}
below are the two repository interfaces which extends MongoRepository<>下面是扩展 MongoRepository<> 的两个存储库接口
CustomerRepository客户资料库
package com.devzigma.repository;
import com.devzigma.model.Customer;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface CustomerRepository extends MongoRepository<Customer, String> {
}
OrderRepository订单库
package com.devzigma.repository;
import com.devzigma.model.Order;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface OrderRepository extends MongoRepository<Order, String> {
}
In the services package I have CustomerService and OrderService interfaces with their respective implementations.在服务包中,我有 CustomerService 和 OrderService 接口以及它们各自的实现。
CustomerService and it's implementation CustomerService及其实现
package com.devzigma.services;
import com.devzigma.model.Customer;
import java.util.List;
import java.util.Optional;
public interface CustomerService {
Optional<Customer> getCustomerDetail(String id);
List<Customer> allCustomers();
}
package com.devzigma.services;
import com.devzigma.model.Customer;
import com.devzigma.repository.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerRepository customerRepository;
@Override
public Optional<Customer> getCustomerDetail(String id) {
return customerRepository.findById(id);
}
@Override
public List<Customer> allCustomers() {
return customerRepository.findAll();
}
}
then the OrderService with it's implementation然后是 OrderService 及其实现
package com.devzigma.services;
import com.devzigma.model.Order;
import java.util.Optional;
public interface OrderService {
Optional<Order> getAllOrdersForCustomer(String customerId);
}
package com.devzigma.services;
import com.devzigma.model.Order;
import com.devzigma.repository.CustomerRepository;
import com.devzigma.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private OrderRepository orderRepository;
@Override
public Optional<Order> getAllOrdersForCustomer(String customerId) {
return orderRepository.findById(customerId);
}
}
In my main class I have implements the CommandLineRunner so that I can populate MongoDB database with sample data.在我的主类中,我实现了 CommandLineRunner,以便我可以使用示例数据填充 MongoDB 数据库。
below is the main class.下面是主类。
package com.devzigma;
import com.devzigma.model.Customer;
import com.devzigma.model.Order;
import com.devzigma.repository.CustomerRepository;
import com.devzigma.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.HashMap;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private OrderRepository orderRepository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
customerRepository.deleteAll();
orderRepository.deleteAll();
final Customer customer1 = new Customer("10A", "Jane", "ABC Company");
final Customer customer2 = new Customer("20B", "Bob", "XYZ Company");
final Customer customer3 = new Customer("30C", "Tim", "CKV Company");
HashMap<String, Order> cus1order = new HashMap<>();
cus1order.put("001A", new Order("001A", 150.00, 25));
cus1order.put("002A", new Order("002A", 250.00, 15));
customer1.setOrders(cus1order);
customerRepository.save(customer1);
customerRepository.save(customer2);
customerRepository.save(customer3);
}
}
finally , below is my application.properties file最后,下面是我的 application.properties 文件
server.port=8086
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.uri=mongodb://localhost:27017/customer-order
I know this is lot of boilerplate code.我知道这是很多样板代码。 but please bear with me.但请耐心等待。 If can anyone give my insight how to fix above error which was given as the stacktrace, then it would be much appreciated.如果有人能告诉我如何解决作为堆栈跟踪给出的上述错误,那么将不胜感激。
Good day!再会!
One possible way to resolve this exception is to make the property mutable via a setter (assuming it's acceptable to persist an empty links collection):解决此异常的一种可能方法是通过 setter 使属性可变(假设保留空链接集合是可以接受的):
@AccessType(AccessType.Type.PROPERTY)
public void setLinks(List<Link> links) {
super.removeLinks();
super.add(links);
}
You can even place this in a custom parent class and have that class extend RepresentationModel, eg:您甚至可以将其放在自定义父类中,并让该类扩展 RepresentationModel,例如:
public abstract class MyRepresentationModel extends RepresentationModel<MyRepresentationModel> { ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.