I've been trying to set up a rest service using spring data rest and spring boot. I followed the tutorial at https://spring.io/guides/gs/accessing-data-rest/ but the expected rest endpoints were not created on startup, and calling get methods on them only led to a 404. I can create an endpoint with RestController, but not with RepositoryRestResource. I am using Spring Boot 2 and hibernate 5.2, with postgres as the backing datastore. I am using eclipse, and have tried running the application via Run Java Application in eclipse, as well as running it from the windows command line using java -jar. The output and end result is the same. Does anybody know what I'm doing wrong and what I need to do for the expected endpoints to be created by the RepositoryRestResource? I've put example code below, with the spring boot output at the bottom, but first here are some similar questions and what I've tried:
this question has an accepted answer which seems to suggest its an entity scanning issue. However, I have added EntityScan to the Application and that didn't seem to help. RepositoryRestResource with spring-boot CLI
this question has an answer suggesting wrapping the repository in a controller class with RestController instead of using RepositoryRestResource. I can do that, but I don't want to write all the extra code, I would rather that RepositoryRestResource work instead. Clueless what I'm doing wrong setting up Spring Boot REST app
project structure:
pom.xml
src/main/java/com/springdataresttest/
Application.java
src/main/java/com/springdataresttest/entity/
Thing.java
src/main/java/com/springdataresttest/repository/
ThingRepository.java
src/main/resources/
application.properties
hibernate.properties
postgres ddl:
CREATE TABLE thing
(
id serial,
name varchar(255),
PRIMARY KEY (id)
)
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springdataresttest</groupId>
<artifactId>springdataresttest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.java:
package com.springdataresttest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
@SpringBootApplication
@EntityScan(basePackages = {"com.springdataresttest.entity"})
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
Thing.java:
package com.springdataresttest.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "thing")
public class Thing {
private Integer id;
private String name;
@Id
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ThingRepository.java:
package com.springdataresttest.repository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import com.springdataresttest.entity.Thing;
@RepositoryRestResource(collectionResourceRel = "things", path = "things")
public interface ThingRepository extends PagingAndSortingRepository<Thing, Integer>{
}
application.properties:
security.basic.enabled=false
management.security.enabled=false
security.ignored=/**
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/springdataresttest
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=none
spring.datasource.platform=POSTGRESQL
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.properties:
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.connection.url=jdbc:postgresql://127.0.0.1:5432/springdataresttest
hibernate.connection.username=postgres
hibernate.connection.password=password
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.schema=public
output from spring boot (notice that rest repository endpoints for "things" are not mapped)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)
2018-08-23 14:57:51.118 INFO 1336 --- [ main] com.springdataresttest.Application : Starting Application on LTW10me with PID 1336 (C:\Users\me.HQ\workspace\springdataresttest\target\classes started by me in C:\Users\me.HQ\workspace\springdataresttest)
2018-08-23 14:57:51.123 INFO 1336 --- [ main] com.springdataresttest.Application : No active profile set, falling back to default profiles: default
2018-08-23 14:57:51.233 INFO 1336 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6646153: startup date [Thu Aug 23 14:57:51 EDT 2018]; root of context hierarchy
2018-08-23 14:57:52.882 INFO 1336 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$ca53dd09] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-08-23 14:57:53.548 INFO 1336 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2018-08-23 14:57:53.583 INFO 1336 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-08-23 14:57:53.583 INFO 1336 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.31
2018-08-23 14:57:53.593 INFO 1336 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_112\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_171/bin/server;C:/Program Files/Java/jre1.8.0_171/bin;C:/Program Files/Java/jre1.8.0_171/lib/amd64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\PuTTY\;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\Bitvise SSH Client;C:\Program Files\TortoiseGit\bin;C:\Program Files\Git\cmd;C:\Program Files (x86)\Yarn\bin\;C:\Program Files\nodejs\;C:\WINDOWS\System32\OpenSSH\;"C:\Users\me.HQ\AppData\Local\Microsoft\WindowsApps;C:\Program Files (x86)\PuTTY;C:\Program Files\PostgreSQL\9.6\bin;C:\cygwin64;C;\cygwin64\bin;";C:\Users\me.HQ\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\Microsoft VS Code\bin;C:\Users\me.HQ\AppData\Local\Yarn\bin;C:\Users\me.HQ\AppData\Roaming\npm;C:\eclipse;;.]
2018-08-23 14:57:53.709 INFO 1336 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-08-23 14:57:53.709 INFO 1336 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2481 ms
2018-08-23 14:57:53.876 INFO 1336 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-08-23 14:57:53.881 INFO 1336 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-08-23 14:57:53.881 INFO 1336 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-08-23 14:57:53.881 INFO 1336 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-08-23 14:57:53.886 INFO 1336 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-08-23 14:57:54.138 INFO 1336 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2018-08-23 14:57:54.720 INFO 1336 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2018-08-23 14:57:54.768 INFO 1336 --- [ main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-08-23 14:57:54.793 INFO 1336 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2018-08-23 14:57:54.944 INFO 1336 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.2.17.Final}
2018-08-23 14:57:54.947 INFO 1336 --- [ main] org.hibernate.cfg.Environment : HHH000205: Loaded properties from resource hibernate.properties: {hibernate.connection.username=postgres, hibernate.schema=public, hibernate.connection.password=****, hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect, hibernate.connection.url=jdbc:postgresql://127.0.0.1:5432/springdataresttest, hibernate.bytecode.use_reflection_optimizer=false, hibernate.connection.driver_class=org.postgresql.Driver}
2018-08-23 14:57:55.015 INFO 1336 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-08-23 14:57:55.155 WARN 1336 --- [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata : null
2018-08-23 14:57:55.168 INFO 1336 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2018-08-23 14:57:55.188 INFO 1336 --- [ main] o.h.e.j.e.i.LobCreatorBuilderImpl : HHH000422: Disabling contextual LOB creation as connection was null
2018-08-23 14:57:55.193 INFO 1336 --- [ main] org.hibernate.type.BasicTypeRegistry : HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@64f16277
2018-08-23 14:57:55.716 INFO 1336 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-08-23 14:57:55.851 INFO 1336 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-08-23 14:57:56.594 INFO 1336 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6646153: startup date [Thu Aug 23 14:57:51 EDT 2018]; root of context hierarchy
2018-08-23 14:57:56.653 WARN 1336 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2018-08-23 14:57:56.698 INFO 1336 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-08-23 14:57:56.703 INFO 1336 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-08-23 14:57:56.748 INFO 1336 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-08-23 14:57:56.749 INFO 1336 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-08-23 14:57:57.112 INFO 1336 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-08-23 14:57:57.115 INFO 1336 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-08-23 14:57:57.120 INFO 1336 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-08-23 14:57:57.170 INFO 1336 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-08-23 14:57:57.180 INFO 1336 --- [ main] com.springdataresttest.Application : Started Application in 6.496 seconds (JVM running for 6.954)