无法解析JSON对象并将其插入数据库

时间:2019-07-31 17:49:25

标签: json hibernate spring-boot spring-data-jpa

我在解析JSON对象时遇到问题。 JSON表示用户下的订单。

这以前曾起作用,但是向项目中添加其他实体/ DTO导致了一些问题。更具体地说,JSON如下所示:

{
    "orderElements": [
        {
            "product": {
                "id": 3,
                "name": "xxx",
                "description": "yyy",
                "category": {
                    "id": 2,
                    "name": "xxx"
                },
                "price": 11,
                "count": 1
            },
            "quantity": 1
        }
    ],
    "user": {
        "id": 110,
        "lastName": "xxx",
        "firstName": "xxx",
        "addressLine": "xxx",
        "city": "xxx",
        "country": "xxx",
        "zipCode": "123456",
        "phoneNumber": "1234567",
        "password": "xxxx",
        "email": "xxxx",
        "roles": [
            "USER"
        ]
    },
    "orderPlaceTime": null,
    "deliveryAddress": {
        "street": "xxx",
        "city": "xxx",
        "zipCode": "xxx"
    }
}

如果发送时不带“ deliveryAddress”部分,则表示JSON已正确解析,并且一切正常。但是,尝试使用“ deliveryAddress”及其所有内容发送JSON会导致NullPointerException。

尽管调试前端显示整个JSON已正确填充-street,city和zipCode字段包含用户已放置的所有数据(以上正是“ POST”发送的数据-后端填充了“ orderPlaceTime”通过LocalDateTime.now()函数)。

订购

@Entity
@Table(name = "carts")
public class Order extends AbstractEntity {

    @Fetch(FetchMode.SELECT)
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "id_order")
    @JsonIgnore
    private Set<OrderElement> orderElements;

    @Column
    private LocalDateTime orderPlaceTime;

    @ManyToOne
    @JoinColumn(name = "id_user")
    private User user;

    @ManyToOne
    @JoinColumn(name = "id_delivery")
    private DeliveryAddress deliveryAddress;

    public DeliveryAddress getDeliveryAddress() {
        return deliveryAddress;
    }

    public void setDeliveryAddress(DeliveryAddress deliveryAddress) {
        this.deliveryAddress = deliveryAddress;
    }

    public Set<OrderElement> getOrderElements() {
        return orderElements;
    }

    public void setOrderElements(Set<OrderElement> orderElements) {
        this.orderElements = orderElements;
    }

    public LocalDateTime getOrderPlaceTime() {
        return orderPlaceTime;
    }

    public void setOrderPlaceTime(LocalDateTime orderPlaceTime) {
        this.orderPlaceTime = orderPlaceTime;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

}

交付地址

@Entity
@Table(name = "delivery_address")
public class DeliveryAddress extends AbstractEntity {

    @Column
    private String street;

    @Column
    private String city;

    @Column
    private String zipCode;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

订单转换器

@Component
public class OrderConverter implements Converter<Order, OrderDTO> {

    private final OrderElementConverter orderElementConverter;
    private final DeliveryAddressConverter deliveryAddressConverter;
    private final UserConverter userConverter;

    public OrderConverter(OrderElementConverter orderElementConverter, DeliveryAddressConverter deliveryAddressConverter, UserConverter userConverter) {
        this.orderElementConverter = orderElementConverter;
        this.deliveryAddressConverter = deliveryAddressConverter;
        this.userConverter = userConverter;
    }

    @Override
    public Order convertToEntity(OrderDTO dto) {
        Order order = new Order();
        order.setId(dto.getId());
        order.setUser(userConverter.convertToEntity(dto.getUser()));
        order.setOrderPlaceTime(now());
        Set<OrderElement> entitySet = new HashSet<>();
        for (OrderElementDTO o : dto.getOrderElements()) {
            entitySet.add(orderElementConverter.convertToEntity(o));
        }
        order.setOrderElements(entitySet);
    // this below throws NullPointerException --> dto.getDeliveryAddressDTO();
        order.setDeliveryAddress(deliveryAddressConverter.convertToEntity(dto.getDeliveryAddressDTO()));
        return order;
    }
}

交付地址转换器

@Component
public class DeliveryAddressConverter implements Converter<DeliveryAddress, DeliveryAddressDTO> {

    @Override
    public DeliveryAddress convertToEntity(DeliveryAddressDTO dto) {
        DeliveryAddress deliveryAddress = new DeliveryAddress();
        deliveryAddress.setId(dto.getId());
        deliveryAddress.setCity(dto.getCity());
        deliveryAddress.setZipCode(dto.getZipCode());
        deliveryAddress.setStreet(dto.getStreet());
        return deliveryAddress;
    }
}

我不知道为什么前端正确发送的deliveryAddress为null。

感谢您提供所有答案和建议

编辑

事实证明,正如OrderDTO中的JB Nizet字段所指出的,该字段具有“ deliveryAddressDTO”而不是“ deliveryAddress”。从名称中删除“ DTO”可解决此问题:

public class OrderDTO extends AbstractDTO {

    private Set<OrderElementDTO> orderElements;

    private LocalDateTime orderPlaceTime;

    private UserDTO user;

    private DeliveryAddressDTO deliveryAddress;
    // private DeliveryAddressDTO deliveryAddressDTO; <-- wrong name, methods also aligned

    public DeliveryAddressDTO getDeliveryAddress() {
        return deliveryAddress;
    }

    public void setDeliveryAddressDTO(DeliveryAddressDTO deliveryAddress) {
        this.deliveryAddress = deliveryAddress;
    }


    public Set<OrderElementDTO> getOrderElements() {
        return orderElements;
    }

    public void setOrderElements(Set<OrderElementDTO> orderElements) {
        this.orderElements = orderElements;
    }

    public LocalDateTime getOrderPlaceTime() {
        return orderPlaceTime;
    }

    public void setOrderPlaceTime(LocalDateTime orderPlaceTime) {
        this.orderPlaceTime = orderPlaceTime;
    }

    public UserDTO getUser() {
        return user;
    }

    public void setUser(UserDTO user) {
        this.user = user;
    }
}

1 个答案:

答案 0 :(得分:0)

事实证明,正如OrderDTO中的JB Nizet字段所指出的,该字段具有“ deliveryAddressDTO”而不是“ deliveryAddress”。从名称中删除“ DTO”可解决此问题:

public class OrderDTO extends AbstractDTO {

    private Set<OrderElementDTO> orderElements;

    private LocalDateTime orderPlaceTime;

    private UserDTO user;

    private DeliveryAddressDTO deliveryAddress;
    // private DeliveryAddressDTO deliveryAddressDTO; <-- wrong name, methods also aligned

    public DeliveryAddressDTO getDeliveryAddress() {
        return deliveryAddress;
    }

    public void setDeliveryAddressDTO(DeliveryAddressDTO deliveryAddress) {
        this.deliveryAddress = deliveryAddress;
    }


    public Set<OrderElementDTO> getOrderElements() {
        return orderElements;
    }

    public void setOrderElements(Set<OrderElementDTO> orderElements) {
        this.orderElements = orderElements;
    }

    public LocalDateTime getOrderPlaceTime() {
        return orderPlaceTime;
    }

    public void setOrderPlaceTime(LocalDateTime orderPlaceTime) {
        this.orderPlaceTime = orderPlaceTime;
    }

    public UserDTO getUser() {
        return user;
    }

    public void setUser(UserDTO user) {
        this.user = user;
    }
}

JB Nizet还解决了id_delivery问题-向ManyToOne添加层叠.ALL注释解决了所有问题。

谢谢!