Expose all IDs when using Spring Data Rest

Currently, there is no way to do this provided by SDR. This issue on the SDR Jira tracker gives some explanation as to why this isn't (and perhaps shouldn't) be possible.

The argument is basically that since the IDs are already contained within the self links in the response, you don't need to expose them as properties of the object itself.

That said, you may be able to use reflection to retrieve all classes that have a javax.persistence.Id annotation and then call RepositoryRestConfiguration#exposeIdsFor(Class<?>... domainTypes).


If you want to expose the id field for all your entity classes:

import java.util.stream.Collectors;

import javax.persistence.EntityManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;

@Configuration
public class MyRepositoryRestConfigurerAdapter extends RepositoryRestConfigurerAdapter {

    @Autowired
    private EntityManager entityManager;

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(entityManager.getMetamodel().getEntities().stream().map(e -> e.getJavaType()).collect(Collectors.toList()).toArray(new Class[0]));
    }

}

I discovered that if you name the @Id field 'Id' it will display in the JSON if you have a public getter for the Id. The Id will show up as a JSON key called 'id'

For example: @Id @Column(name="PERSON_ROLE_ID") private Long Id;

This also works for @EmbeddedId fields called 'Id' as well as long as it has a public getter. In this case the fields of the Id will show up as a JSON object.

For example: @EmbeddedId private PrimaryKey Id;

Surprisingly this is case sensitive, calling id 'id' doesn't work even though it would be a more conventional name for a Java field.

I should say that I discovered this completely by accident so I don't know if this is an accepted convention or will work with previous or future versions of Spring Data and REST. Therefore I have included the relevant parts of my maven pom just incase it's sensittive to versions...

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc7</artifactId>
        <version>12.1.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>
</dependencies>