Spica
Spica

Reputation: 93

How to make Spring Data Rest work with reference to the same entity type?

I have this entity:

@Entity
@Data
@NoArgsConstructor
@Table(name = "employees")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "employee_id")
    private Long id;

    private String firstName;

    private String lastName;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn(name = "manager_id")
    private Employee manager;
}

With corresponding repository:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    // ..
}

When I make a GET request to find employee by id I get this result:

{
   "firstName":"Steven",
   "lastName":"King",
   "_links":{
      "self":{
         "href":"http://localhost:8081/api/employees/100"
      },
      "employee":{
         "href":"http://localhost:8081/api/employees/100"
      },
      "manager":{
         "href":"http://localhost:8081/api/employees/100/manager"
      }
   }
}

The http://localhost:8081/api/employees/100/manager just doesn't work with Lazy fetching, so how do I change it to something like: http://localhost:8081/api/employees/99 where 99 is the id of Steven's manager?

Upvotes: 0

Views: 473

Answers (1)

yejianfengblue
yejianfengblue

Reputation: 2439

According to Spring Data REST Reference, you can define a bean of type RepresentationModelProcessor<EntityModel<T>>, which are automatically picked up by Spring Data REST when serializing an entity of type T.

You can build an EntityModel there by yourself.

@Component
public class EmployeeModelProcessor implements RepresentationModelProcessor<EntityModel<Employee>> {

    private final RepositoryEntityLinks entityLinks;

    public EmployeeModelProcessor(RepositoryEntityLinks entityLinks) {
        this.entityLinks = entityLinks;
    }

    @Override
    public EntityModel<Employee> process(EntityModel<Employee> employeeModel) {

        Employee employee = employeeModel.getContent();

        EntityModel<Employee> newEmployeeModel = EntityModel.of(employee);
        newEmployeeModel.add(employeeModel.getRequiredLink(IanaLinkRelations.SELF));
        newEmployeeModel.add(employeeModel.getRequiredLink("employee"));

        if (null != employee.getManager()) {
            newEmployeeModel.add(entityLinks.linkToItemResource(Employee.class, employee.getManager().getId()).withRel("manager"));
        }

        return newEmployeeModel;
    }

}

You can find documentation about RepositoryEntityLinks here.

Then the response JSON should become

{
   "firstName":"Steven",
   "lastName":"King",
   "_links":{
      "self":{
         "href":"http://localhost:8081/api/employees/100"
      },
      "employee":{
         "href":"http://localhost:8081/api/employees/100"
      },
      "manager":{
         "href":"http://localhost:8081/api/employees/99"
      }
   }
}

Upvotes: 1

Related Questions