21

This question is related to this SO question (Spring boot @ResponseBody doesn't serialize entity id). I have observed that after migrating an app to Spring Boot and using the spring-boot-starter-data-rest dependency, my entity @Id fields are no longer marshalled in the resulting JSON.

This is my request mapping and while debugging, I can see the data isn't being changed prior to returning it, so the @Id properties are being stripped later on.

@RequestMapping(method = RequestMethod.GET, produces = {"application/json"})
public PagedResources<Receipt> receipts(Pageable pageable, PagedResourcesAssembler assembler) {
    Page<Receipt> receipts = receiptRepository.findByStorerAndCreatedDateGreaterThanEqual("003845", createdStartDate, pageable);
    PagedResources<Receipt> pagedResources = assembler.toResource(receipts, receiptResourceAssembler);
    return pagedResources;
}

Is there a setting that would allow me to keep the @Id field in the resulting JSON because my app allows the user to search by that value.

Thanks :)

lcnicolau
  • 3,252
  • 4
  • 36
  • 53
Patrick Grimard
  • 7,033
  • 8
  • 51
  • 68
  • Take a look at [this](https://stackoverflow.com/a/49344988/4071001) in case you need to expose the identifiers for all entities, or only for those that extends or implements specific super class or interface. – lcnicolau Jun 27 '18 at 23:48

5 Answers5

26

By default Spring Data Rest does not spit out IDs. However you can selectively enable it through exposeIdsFor(..) method. You could do this in configuration, something like this

@Configuration
public static class RepositoryConfig extends
        RepositoryRestMvcConfiguration {

    @Override
    protected void configureRepositoryRestConfiguration(
            RepositoryRestConfiguration config) {
        config.exposeIdsFor(Class1.class, Class2.class);
    }
}
bluish
  • 26,356
  • 27
  • 122
  • 180
Stackee007
  • 3,196
  • 1
  • 26
  • 39
  • 4
    It should be noted that if you are using spring-boot, you need to extend `SpringBootRepositoryRestMvcConfiguration` instead of `RepositoryRestMvcConfiguration` and make it a normal class not a static class. – jax Mar 02 '15 at 02:58
  • 9
    Since version 2.4, `configureRepositoryRestConfiguration` method should be overriden by extending `RepositoryRestConfigurerAdapter` class instead. – Can Bayburt Dec 01 '15 at 09:25
  • 2
    And don't forget to support now getter and setter for the id field in the entity class!.. (I forgot it and was searching much time for that) – phil Apr 21 '16 at 18:11
  • 4
    Is there in SpringBoot 1.3.* any setting that allows to expose all the id's at once by default? Or do I have to list them manually in RepositoryConfig class? ;/ – thorinkor Jul 21 '16 at 11:58
21

As of Spring Data Rest 2.4 (which is a transitive dependency if using spring-boot 1.3.0.M5) you may use the RepositoryRestConfigurerAdapter. For instance,

@Configuration
class SpringDataRestConfig {

    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer() {

        return new RepositoryRestConfigurerAdapter() {
            @Override
            public void configureRepositoryRestConfiguration(
                                 RepositoryRestConfiguration config) {
                config.exposeIdsFor(Class1.class, Class2.class);
            }
        }

    }

}
Ryan Parrish
  • 211
  • 2
  • 3
9

Before expose Id please read disussion: https://github.com/spring-projects/spring-hateoas/issues/66

In REST the id of a resource is its URI. The client doesn't explicitly use the id to build an url. You could, for example, replace your id for an uuid, for example. Or even change the url scheme.

Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197
2

put @getter, @setters and it will be exposed to json results, hope it would help you

leon_
  • 74
  • 3
0

@Id annotation in your model class does the magic.

public class Location {

    @Id
    private String woeid;
    private String locationName;

Then your mongo object will look like this:

{
    "_id" : "2487889",
    "_class" : "com.agilisys.weatherdashboard.Location",
    "locationName" : "San Diego, CA"
}
julianm
  • 2,393
  • 1
  • 23
  • 24