Spring-boot: id field stripping from returned json in responsebody

Created on 12 Jun 2014  路  14Comments  路  Source: spring-projects/spring-boot

After updating to the latest spring boot, it appears that objects with an 'Id" field have this field removed from the json in the response.

invalid

Most helpful comment

Instead I created an alias of id and used the Jackson annotation @JsonProperty("id") which seemed to do the trick for my situation. I was using spring-boot-starter-data-mongodb, spring-boot-starter-data-rest, spring-boot-starter-web and spring-boot-starter-parent all on version 1.2.7.RELEASE .

import org.springframework.data.annotation.Id;
import com.fasterxml.jackson.annotation.JsonProperty;

 public class Calculation {

    @Id private String id;

    private String equation;
    private String result;

    @JsonProperty ("id")
    private String emberId;


    public String getEmberId() {
        return id;
    }

All 14 comments

Can you provide some more information please? Boot itself doesn't do anything with your app's JSON payloads. Are you using any of the Spring Data projects? Also, what version of Boot did you move from?

I haven't been able to reproduce this with a different class, but I still have issue with my controller, and only thing I changed was upgrade from spring-boot 1.0.0.RELEASE to 1.1.0.RELEASE.

Controller code is...

        anonUsers = new ArrayList<AnonUser>();
        aUser = new AnonUser("testId","testAlias","testGroupid","testGroupName");
        anonUsers.add(aUser);
        logger.info("AnonUsers: "+anonUsers.toString());
        return anonUsers;

Log output is as expected...

AnonUsers: [AnonUser{id='testId', alias='testAlias', groupId='testGroupid', groupName='testGroupName'}]

Response is missing "id" field...

[ {
  "alias" : "testAlias",
  "groupId" : "testGroupid",
  "groupName" : "testGroupName"
} ]

I found that commenting out the repository interface that for this object fixed the problem. I'm using using spring-boot-starter-data-mongodb. Anyone have any thoughts as to why this may have occurred, and the relationship with spring-boot 1.1.0.RELEASE

The version of Spring Data MongoDB that you're using has changed. Boot 1.0.x used 1.4.2.RELEASE whereas 1.1.0 uses 1.5.0.RELEASE. I suspect that change in version is what's caused the behaviour difference. @olivergierke will hopefully be able to confirm one way or the other.

It would be helpful to find out more about the project at hand? Are you using Spring Data REST or are you manually coding controllers? In SD REST, id's are not rendered by default, as in a REST world, the URI _is_ the id and persistence internals (the synthetic identifier) must not be revealed to the clients.

If you have manually implemented controllers, I'd really like to see a sample project as it's a bit hard to judge otherwise. Actually, if you're just taking objects you persisted through Spring Data MongoDB, Spring Data doesn't even play into the Jackson serialization.

I have recreated this issue with a test controller. This is a @RestController, but it behaves as expected serving full JSON including id field until a repository for TestObj is autowired in, at which point the id field disappears from the JSON.
The response method...

@RequestMapping(value = "/testObj", method = RequestMethod.GET)
    public Iterable<TestObj> testController() {
        List<TestObj> testList = new ArrayList<>();
        testList.add(new TestObj("test-id-1","Test Name 1"));
        testList.add(new TestObj("test-id-2","Test Name 2"));
        logger.debug(testList.toString());
        Iterable<TestObj> testIt = toRep.findAll();
        return testList;
    }

The java object...

public class TestObj {
    private String id;
    private String name;

    public TestObj() {

    }

    public TestObj(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "TestObj{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

The repository...

@Repository
public interface TestObjRepository extends CrudRepository<TestObj, String> {
}

Result with no repository ...

[ {
  "id" : "test-id-1",
  "name" : "Test Name 1"
}, {
  "id" : "test-id-2",
  "name" : "Test Name 2"
} ]

Result with repository...

[ {
  "name" : "Test Name 1"
}, {
  "name" : "Test Name 2"
} ]

Do you have the test project somewhere? You don't even return the data returned by the repository o.O.

Yes, that's right. Just including the repository causes the "id" issue - it doesn't even need to be in use, which is why it took me a while to find the issue. Any ideas for a work around?
I don't have the test project anywhere public, but I could probably put it on github for you to see.

I've created a new test project from scratch, but I'm unable to reproduce the issue, so I'm guessing there must be some strange interaction between libraries in the previous project.

Since not being able to reproduce this in a new project, I went back to my main project and upgraded my 'non-spring' gradle dependencies, and removed any spring-boot dependencies that may have been superfluous, and rebuilt the project. The issue appears to be fixed. So I'll close this item as it appears to be a dependency conflict issue rather than an issue with the spring-boot version change.
Thanks for your help.

A possible configuration point that might be related to the issue :

  • RepositoryRestMvcConfiguration#configureRepositoryRestConfiguration(RepositoryRestConfiguration)
  • RepositoryRestConfiguration#exposeIdsFor(Class<?>...)

just a little memo for reference :)

Got the same issuse.
This works for me, thanks @wookayin

    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config)
    {
        super.configureRepositoryRestConfiguration(config);
        config.exposeIdsFor(SMS.class, Note.class, ChatMessage.class, ZoneMessage.class);
    }

Instead I created an alias of id and used the Jackson annotation @JsonProperty("id") which seemed to do the trick for my situation. I was using spring-boot-starter-data-mongodb, spring-boot-starter-data-rest, spring-boot-starter-web and spring-boot-starter-parent all on version 1.2.7.RELEASE .

import org.springframework.data.annotation.Id;
import com.fasterxml.jackson.annotation.JsonProperty;

 public class Calculation {

    @Id private String id;

    private String equation;
    private String result;

    @JsonProperty ("id")
    private String emberId;


    public String getEmberId() {
        return id;
    }

@wenerme thank you. I had the issue of the id and I fixed with your trick "repositoryRestConfiguration.exposeIdsFor(Person.class);"

Was this page helpful?
0 / 5 - 0 ratings