4

I have an application with Spring Data REST that returns this JSON:

{
  "_embedded" : {
    "persons" : [ {
      "personDetail" : {
        "name" : "Alex",
        "surname" : "Red",
        "id" : {
          "group" : "A",
          "subclass" : "1"
        },
        "_links" : {
          "self" : {
            "href" : "https ://localhost:8080/myApp/api/personDetails/A_1"
          }
        }
      }
     }]
    }
}   

When I go to the url:

https ://localhost:8080/myApp/api/personDetails/A_1

or to this url:

https ://localhost:8080/myApp/api/persons/04ee99a5-1578-400a-84be-d1ca87cda752/personDetail

The app returns this JSON:

{
  "name" : "Alex",
  "surname" : "Red",
  "_links" : {
    "self" : {
      "href" : "https ://localhost:8080/myApp/api/personDetails/A_1"
    },
    "personDetail" : {
      "href" : "https ://localhost:8080/myApp/api/personDetails/A_1"
    }
  }
}

The "id" field seems to be disappeared. Where is finished? How can I do to have the correct object projection?

This is the Person Class:

@Entity
@Table
public class Person {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)", length = 16)
    private UUID id;

    @ManyToOne(fetch = FetchType.EAGER)
    private PersonDetail personDetail;

    public UUID getId() {
        return id;
    }

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

    public PersonDetail getPersonDetail() {
        return personDetail;
    }

    public void setPersonDetail(PersonDetail personDetail) {
        this.personDetail = personDetail;
    }
}

This is the PersonDetail Class:

@Entity
@Table
public class PersonDetail {
    @EmbeddedId
    private PersonDetailId id;

    @Column
    private String name;

    @Column
    private String surname;

    public PersonDetailId getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    protected String[] getExcludeFieldNames() {
        return null;
    }

    @Override
    public String toString() {
        return ReflectionToStringBuilder.toStringExclude(this, getExcludeFieldNames());
    }
}

This is PersonDetailId class:

public class PersonDetailId implements Serializable {

    @Column(name = "group", nullable = false)
    private String group;

    @Column(name = "subclass", nullable = false)
    private String subclass;

    public PersonDetailId() {
        super();
    }

    public PersonDetailId(String group, String subclass) {
        super();
        this.group = group;
        this.subclass = subclass;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getSubclass() {
        return subclass;
    }

    public void setSubclass(String subclass) {
        this.subclass = subclass;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(group).append("_").append(subclass);
        return builder.toString();
    }

}

This is the repository REST:

@RepositoryRestResource
public interface PersonDetailRepository extends JpaRepository<PersonDetail, PersonDetailId> {

    @RestResource(exported=false)
    PersonDetail findBySurname(String surname);

}

This is the Converter that I used:

@Component
public class PersonDetailIdConverter implements Converter<String, PersonDetailId> {

    @Autowired
    private PersonDetailRepository personDetailRepository;

    @Override
    public PersonDetailId convert(String source) {

        PersonDetailId result = null;

        List<PersonDetail> details = personDetailRepository.findAll();
        for (PersonDetail detail:details) {
            if (detail.getId().toString().equals(source)) {
                result = detail.getId();
                break;
            }
        }

        return result;
    }

}

And this is the configuration that registers that converter:

@Configuration
public class CustomizedRestMvcConfiguration extends RepositoryRestConfigurerAdapter {

    @Bean
    PersonDetailIdConverter personDetailIdConverter(){
        return new PersonDetailIdConverter();
    }

    @Override
    public void configureConversionService(ConfigurableConversionService conversionService) {
        conversionService.addConverter(personDetailIdConverter());
        super.configureConversionService(conversionService);
    }

}

I used the converter because it's the only way to make working the url:

"href" : "https ://localhost:8080/myApp/api/personDetails/A_1"

Any idea? Thanks.

EDIT

It seems that it depends by projections. When I go to the link of the object using the projection that I have created, so the returned JSON contains all the values that I need.

Alessandro C
  • 3,310
  • 9
  • 46
  • 82
  • ia it spring boot,yes, so its doesnt expose ids by default..ref:http://stackoverflow.com/questions/24936636/while-using-spring-data-rest-after-migrating-an-app-to-spring-boot-i-have-obser – Maheshbabu Jammula Apr 06 '17 at 14:53

2 Answers2

0

Because of this issue where ResourceSupport.getId() has a @JsonIgnore annotation on it, Spring Data REST will not export the IDs of your entities. You can however rename them e.g. to personId (or just rename your getter method).

Also remember to expose your IDs, as Alessandro C mentioned.

Adam Kučera
  • 424
  • 5
  • 15
0

From spring 3.1 onwards, this is how to register the converter:

@Import(RepositoryRestMvcConfiguration.class)
public class CustomizedRestMvcConfiguration implements RepositoryRestConfigurer {

    @Override
    public void configureConversionService(ConfigurableConversionService conversionService) {
        conversionService.addConverter(new PersonDetailIdConverter());
        super.configureConversionService(conversionService);
    }

}
vahbuna
  • 31
  • 3