I can't figure out how to do something that should be incredibly simple.
I have two objects: a shelf and a book. A shelf may have one or more books. Each of these objects has a corresponding JpaRepository open as a rest repository using Spring Data Rest. When I run the application, all the query endpoints work fine, but I canβt understand how I can add the book to the shelf.
First I add a shelf using POSTing {"name": "westerns"} to the shelves (works fine).
Method 1: I'm trying to add a POSTing {"name": "mybook"} book to / shelves / 1 / books, but I get 405 error "method not allowed". Can I publish a book only in the endpoint / books (without writing my own controller, I mean)? And if so, will I need to implement the shelf object to which the book belongs?
Method 2: If I try to add a book by doing PUT to / shelves / 1 using the content {"name": "westerns", "books": [{"name": "mybook"}]}, I get the following message about error:
Message: "Could not read JSON: the template should not be empty or empty! (Via the chain of links: org.demo.Shelf [" books "]); the nested exception is com.fasterxml.jackson.databind.JsonMappingException: The template should not be empty or empty! (via the link chain: org.demo.Shelf ["books"])
Statcktrace:
2014-11-06 06: 55: 18.864 ERROR 9888 --- [nio-8080-exec-5] sdrwAbstractRepositoryRestController: Failed to read JSON: The template must not be empty or empty! (via the link chai n: org.demo.Shelf ["books"]); nested exception com.fasterxml.jackson.databind.JsonMappingException: the template must not be empty or empty! (via the reference chain: org.demo.Shelf ["books"])
org.springframework.http.converter.HttpMessageNotReadableException: Failed to read JSON: the template must not be empty or empty! (via the reference chain: org.demo.Shelf ["books"]); com.fasterxml.jackson.databind.JsonMappingException exception exception: template must not be empty or empty! (via the chain of links: org.demo.Shelf ["books"]) in org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType (MappingJackson2HttpMessageConverter.java:228) in org.springframework.hsonspMttp.convertMonverter.jttpmconverter readInternal (MappingJackson2HttpMessageConverter.java:212) in org.springframework.http.converter.AbstractHttpMessageConverter.read (AbstractHttpMessageConverter.java:159) in org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.resolveArgument (PersistentEntityResourceHandlerMethodArgumentResolver.java:100) in org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument (HandlerMethodArgumentResolverComposite.java:79) in org.springframework.web.method.support.InvocableHandlerMethod.getMethodmentethodemethodmentethodemethodmentethodmodethetchgumentCommentodethethommentodment .method.support.InvocableHandlerMethod.invokeForReq uest (InvocableHandlerMethod.java:124) in org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle (ServletInvocableHandlerMethod.java:104) in org.springframework.mebem. invokeHandleMethod (RequestMappingHandlerAdapter.java:749) in org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal (RequestMappingHandlerAdapter.java:689) in org.springframework.web.servhandMbc.mehand AbstractHandlerMethodAdapter.java:83) in org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:938) in org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:870fwork org .servlet.FrameworkServlet.processRequest (FrameworkServlet.java:961) in org.springframework.web.servlet.FrameworkServlet.doPut (FrameworkServlet.java:874) in javax.servlet.http.HttpServlet.s ervice (HttpServlet.java:649) in org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:837) in javax.servlet.http.HttpServlet.service (HttpServlet.java:727) in org.apache.catalina .core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:303) in org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:208) in org.springframework.web.filter.HiddenHttpMethodFilter.ilterlterterterterterterterterterterterterterter ) in org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) in org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:241) in org.apache.ppalal. doFilter (ApplicationFilterChain.java:208) in org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:220) in org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:122) .catalina.authenticator.Au thenticatorBase.invoke (AuthenticatorBase.javaPoint01) in org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:171) in org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java10 .apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:116) in org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:408) in org.apache.coyote.http11.AbstractHttp11Processor Process Abstract .java: 1070) in org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process (AbstractProtocol.java:611) in org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEndpoint.java:1736) in org. apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run (NioEndpoint.java:1695) in java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145) in java.util.concurrent.ThreadPoolExecutor $ Worker ThreadPoolExecutor.java:615) in org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.ru n (TaskThread.java:61) in java.lang.Thread.run (Thread.java: 745) Called: com.fasterxml.jackson.databind.JsonMappingException: the template must not be empty or empty! (via the link chain: org.demo.Shelf ["books"]) in com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath (JsonMappingException.java:232) in com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath (JsonMappingException. java: 197) in com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow (BeanDeserializerBase.java:1420) in com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize (BeanDeserializer.javaaster4) .jackson. .java: 2158) in org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType (MappingJackson2HttpMessageConverter.java:225) ... 38 common frames omitted Cause: java.lang.IllegalArguExi on: the template must not be null or empty! at org.springframework.util.Assert.hasText (Assert.java:162) at org.springframework.hateoas.UriTemplate. (UriTemplate.java:56) in org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module $ UriStringDeserializer.deserialize (PersistentEntityJackson2Module.javahaps80) in com.fasterxml.jackson.databinderializerizerizerizerizerizer .java: 227) in com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize (CollectionDeserializer.java:204) in com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize (CollectionDeserializer.java:23 ) in com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize (SettableBeanProperty.javahaps25) in com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet (MethodProperty.java:99) in com.fasterml. jackson.databind.deser.BeanDeserializer.vanillaDeserialize (BeanDeserializer.java:242) ... 42 common frames are omitted
Here is all the relevant code (of course, each class is in its own file).
@Entity public class Shelf { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; @OneToMany private List<Book> books; public List<Book> getBooks() { return books; } public void setBooks(List<Book> books) { this.books = books; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @RepositoryRestResource public interface BookRepository extends JpaRepository<Book, Long>{ } @RepositoryRestResource public interface ShelfRepository extends JpaRepository<Shelf, Long>{ }
I am using Spring Boot 1.1.8.RELEASE
spring-boot spring-data-rest
gyoder
source share