【问题标题】:How to make Spring Data Rest work with reference to the same entity type?如何使 Spring Data Rest 参考相同的实体类型工作?
【发布时间】:2021-07-06 20:30:55
【问题描述】:

我有这个实体:

@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;
}

有对应的仓库:

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

当我发出GET 请求以通过id 查找员工时,我得到以下结果:

{
   "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"
      }
   }
}

http://localhost:8081/api/employees/100/manager 不能与 Lazy fetching 一起使用,那么我该如何将其更改为:http://localhost:8081/api/employees/99 其中 99 是 @ 987654329@史蒂文的经理?

【问题讨论】:

    标签: spring spring-boot spring-data-jpa spring-data-rest


    【解决方案1】:

    根据Spring Data REST Reference,可以定义RepresentationModelProcessor&lt;EntityModel&lt;T&gt;&gt;类型的bean,在序列化T类型的实体时,Spring Data REST会自动拾取。

    你可以自己在那里建立一个EntityModel

    @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;
        }
    
    }
    

    您可以找到有关 RepositoryEntityLinks here 的文档。

    那么响应JSON应该变成

    {
       "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"
          }
       }
    }
    

    【讨论】:

    • 其实我有这个结果json "_links": { "self": { "href": "http://localhost:8081/api/employees/101" }, "employee": [ { "href": "http://localhost:8081/api/employees/101" }, { "href": "http://localhost:8081/api/employees/100" } ] } spring HATEOAS 的版本有问题还是我做错了什么?
    • 我更新了我的代码以使用代码.withRel("manager")设置经理链接的rel
    • 感谢您开始使用此功能,接下来我将调查您建议的文档
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2014-08-25
    相关资源
    最近更新 更多