代码之家  ›  专栏  ›  技术社区  ›  Snæbjørn

外键对POST的结果不起作用,但是GET起作用

  •  0
  • Snæbjørn  · 技术社区  · 8 年前

    这个 orderTypeId Order 在创建的响应中丢失,但随后的GET请求产生预期结果。

    下面是一个我想要实现的小例子。

    POST /api/orders
    {
        "orderType": "orderTypes/1",
    }
    

    或 GET /api/orders/2

    输出

    {
        "id": 2,
        "orderTypeId": 1,            // either this
        "orderType": "orderTypes/1"  // or this
        "_links": {
            "self": {
                "href": "http://localhost:8090/api/orders/2"
            },
            "order": {
                "href": "http://localhost:8090/api/orders/2"
            },
            "orderType": {
                "href": "http://localhost:8090/api/orders/2/orderType"
            },
            "orderType": {
                "href": "orderTypes/1" // this could even be acceptable
            }
        }
    }
    

    @Data
    @Entity
    public class Order {
      @Id
      @GeneratedValue
      private Long id;
    
      @Column(name = "order_type_id", nullable = false, insertable = false, updatable = false)
      private Long orderTypeId;
    
      @NotNull
      @ManyToOne
      @JoinColumn(name = "order_type_id")
      private OrderType orderType;
    }
    
    @Data
    @Entity
    public class OrderType {
      @Id
      @GeneratedValue
      private Long id;
    
      @Column(nullable = false)
      private String name;
    
      @JsonIgnore
      @OneToMany(mappedBy = "orderType")
      private List<Order> orders;
    }
    

    控制器

    @RepositoryRestResource
    public interface OrderRepository extends JpaRepository<Order, Long> {}
    

    岗位

    {
    }
    

    输出

    {
        "id": 2,
        "orderTypeId": null,
        "_links": {
            "self": {
                "href": "http://localhost:8090/api/orders/2"
            },
            "order": {
                "href": "http://localhost:8090/api/orders/2"
            },
            "orderType": {
                "href": "http://localhost:8090/api/orders/2/orderType"
            }
        }
    }
    

    GET /orders/2

    我做错什么了?


    我试过别的

    @Data
    @Entity
    public class Order {
      @Id
      @GeneratedValue
      private Long id;
    
      @NotNull
      @ManyToOne
      @JoinColumn
      @JsonManagedReference
      @RestResource(exported=false) // ADDED
      private OrderType orderType;
    }
    
    @Data
    @Entity
    public class OrderType {
      @Id
      @GeneratedValue
      private Long id;
    
      @Column(nullable = false)
      private String name;
    
      // removed orders
    }
    

    获取/api/orders/2

    {
        "id": 2,
        "orderTypeId": {
            "id": 1,
            "name": "foo"
        },
        "_links": {
            "self": {
                "href": "http://localhost:8090/api/orders/2"
            },
            "order": {
                "href": "http://localhost:8090/api/orders/2"
            }
        }
    }
    

    但现在POST不起作用:(

    {
    “orderType”:“orderTypes/1”,
    

    返回400个错误请求。。。

    2 回复  |  直到 8 年前
        1
  •  1
  •   abstractKarshit    8 年前

    使用 @JsonIgnore 不是推荐的方法,要管理循环依赖关系请使用 @JsonManagedReference 实体:

    @Data
    @Entity
    public class Order {
        @Id
        @GeneratedValue
        private Long id;
    
       @Column(name = "order_type_id", nullable = false, insertable = false, updatable = false)
       private Long orderTypeId;
    
       @JsonBackReference(value="name")
       @ManyToOne
       @JoinColumn(name = "order_type_id")
       private OrderType orderType;
    }
    
    
    @Data
    @Entity
    public class OrderType {
       @Id
       @GeneratedValue
       private Long id;
    
       @Column(nullable = false)
       private String name;
    
       @JsonManagedReference(value = "name")
       @OneToMany(mappedBy = "orderType")
       private List<Order> orders;
    }
    

    您可以稍后执行GET调用,因为在您的案例中已经发生了,也可以在保存后在POST api中使用rest控制器。您可以在返回之前按id执行GET调用,或者使用DTO发送响应。

        2
  •  1
  •   Alan Hay    8 年前

    我不太清楚为什么需要将此映射为持久字段。简单地添加getter应该意味着它包含在任何JSON响应中:

    @Data
    @Entity
    public class Order {
      @Id
      @GeneratedValue
      private Long id;
    
      @NotNull
      @ManyToOne
      @JoinColumn(name = "order_type_id")
      private OrderType orderType;
    
      public Long getOrderTypeId(){
        return orderType != null ? orderType.getId() : null;
      }
    }
    

    如果失败,则可以为 AfterCreateEvent

    https://docs.spring.io/spring-data/rest/docs/current/reference/html/#events

    或者根据关联的 OrderType EntityManager

    https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#refresh(java.lang.Object)

    @RepositoryEventHandler 
    public class OrderEventHandler {
    
    @PersistenceContext
    private EntityManager em;
    
      @HandleAfterCreate
      public void onOrderCreated(Order o) {
        em.refresh(o);
      }
    }