Jan Nielsen
Jan Nielsen

Reputation: 11849

Statically configure rel in Spring Data REST

I'm profiling a simple Spring Boot 1.5 Spring Data REST application. To my surprise, the Atteo Evo Inflector is a tremendous hot-spot at over half the CPU according to JProfiler:

enter image description here

You should be able to reproduce this with Apache Bench:

ab2 -c 1 -n 10000 http://localhost:8080/people

The repository is:

@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository 
    extends PagingAndSortingRepository<Person, Long> {
    List<Person> findByLastName(@Param("name") String name);
}

and the (Lombok-ed) data:

@Data
@NoArgsConstructor
@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String firstName;
    private String lastName;

    @JsonSerialize(using = MyLocalDateSerializer.class)
    private LocalDate birthDate;

    public Person(String firstName, String lastName, String birthDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.birthDate = LocalDate.parse(birthDate);
    }
}

Why is Spring HATEOAS trying to inflect the @RepositoryRestResource repository when the repository defines the collectionResourceRel statically? Any ideas what the correct annotations are to configure my Spring Data REST application to avoid the runtime inflection overhead?

Upvotes: 2

Views: 411

Answers (1)

Jan Nielsen
Jan Nielsen

Reputation: 11849

Add @RestResource(rel="people", path="people") to your entity: `

@Data
@NoArgsConstructor
@Entity
@RestResource(rel="people", path="people")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String firstName;
    private String lastName;

    @JsonSerialize(using = MyLocalDateSerializer.class)
    private LocalDate birthDate;

    public Person(String firstName, String lastName, String birthDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.birthDate = LocalDate.parse(birthDate);
    }
}

Unfortunately, if Spring HATEOUS does not find a @RestResource annotation on the entity, it delegates to the Atteo Evo Inflection rel provider, even if the entity's repository is a @RepositoryRestResource. Since both the entity and the repository now have rel and path (duplicate) information you need to be careful to keep these in sync. I've opened a Spring Data REST issue on this.

Upvotes: 3

Related Questions