java - 响应不包括关联
问题描述
我正在开发一个 Spring Boot rest api。我有以下两个 Hibernate 实体:
订单实体
@Table(name = "orders")
@Getter
@Setter
public @Entity class OrderEntity extends AbstractPersistable<Long> {
private static final long serialVersionUID = 1780337491454957180L;
@Column(name = "order_number")
@Setter(value = AccessLevel.NONE)
private String orderId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private UserEntity user;
@Digits(integer = 10, fraction = 2)
@Column(name = "total_amount")
@Range(min = 0, message = "The total amount must be greater or equals to zero.")
private BigDecimal totalAmount = BigDecimal.ZERO;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<OrderDetailEntity> items = new HashSet<>();
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(nullable = false, name = "card_details_id")
private CardDetailsEntity card;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(nullable = false, name = "shipping_address_id")
private AddressEntity shippingAddress;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(nullable = true, name = "billing_address_id")
private AddressEntity billingAddress;
@Column(name = "one_address", columnDefinition = "BOOLEAN")
private boolean oneAddress;
public void addOrderDetail(OrderDetailEntity detail) {
items.add(detail);
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(orderId).append(" (").append(totalAmount).append(") ");
items.forEach(i -> buffer.append(i.getProduct().getName()).append("; qty: ").append(i.getQuantity())
.append("; amount: ").append(i.getTotalAmount()).append(System.lineSeparator()));
return buffer.append("]").toString();
}
public void setOrderId(UUID uuid) {
orderId = uuid.toString();
}
}
和:
订单详情实体
@Table(name = "order_detail")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public @Entity class OrderDetailEntity extends AbstractPersistable<Long> {
private static final long serialVersionUID = 8128749778263610480L;
@Column(name = "quantity")
private Integer quantity;
@Digits(integer = 10, fraction = 2)
@Column(name = "total_amount")
@Range(min = 0, message = "The total amount must be greater or equals to zero.")
private BigDecimal totalAmount = BigDecimal.ZERO;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
@JsonBackReference
private OrderEntity order;
@OneToOne(optional = false)
@JoinColumn(name = "product_id")
private ProductEntity product;
}
我还为订单和订单详细信息编写了一个 spring data jpa存储库:
@Repository
public interface OrderRepository extends JpaRepository<OrderEntity, Long> {
@Query("SELECT o FROM OrderEntity o LEFT JOIN FETCH o.items i WHERE o.user.email = ?1")
List<OrderEntity> findOrdersByUser(String email);
}
@Repository
public interface OrderDetailRepository extends JpaRepository<OrderDetailEntity, Long> {
@Query("SELECT d FROM OrderDetailEntity d LEFT JOIN FETCH d.order o WHERE o.orderId = ?1")
List<OrderDetailEntity> findOrderItemsByUser(String orderId);
}
服务:_
@Transactional(readOnly = true)
public List<OrderDetailEntity> getOrderItems(final long userId, final String orderId) {
String currentUser = SecurityUtil.getCurrentUserEmail();
List<OrderDetailEntity> orderDetails = userService.findOneByEmail(currentUser)
.filter(user -> user.getId() == userId)
.map(user -> {
return orderDetailRepository.findOrderItemsByUser(orderId);
}).orElseThrow(() -> new RuntimeException());
return orderDetails;
}
@Transactional(readOnly = true)
public List<OrderEntity> getOrders(final long userId) {
String currentUser = SecurityUtil.getCurrentUserEmail();
List<OrderEntity> orders = userService.findOneByEmail(currentUser)
.filter(user -> user.getId() == userId)
.map(user -> {
return orderRepository.findOrdersByUser(user.getEmail());
}).orElseThrow(() -> new RuntimeException());
return orders;
}
和控制器方法(端点):
@GetMapping("/users/{userId}/orders")
public List<OrderEntity> getOrders(@PathVariable Long userId) {
return orderService.getOrders(userId);
}
@GetMapping("/users/{userId}/orders/{orderId}")
public List<OrderDetailEntity> getOrderItems(@PathVariable Long userId, @PathVariable String orderId) {
return orderService.getOrderItems(userId, orderId);
}
在这两个回复中,都没有包含一些关联。我更好的例子:
如果我发出以下请求:
curl -X GET "http://localhost:8080/users/1/orders/d329cba4-5ead-4f5d-9663-557e99ab46f1"
我收到以下结果:
[ {
"quantity" : 1,
"totalAmount" : 105.00,
"new" : false
} ]
其中不包括product
参考,而仅包括字段数量和totalAmount
。
另外,如果我发出以下请求:
curl -X GET "http://localhost:8080/users/1/orders"
[ {
"created" : "2018-05-12T14:02:00",
"orderId" : "d329cba4-5ead-4f5d-9663-557e99ab46f1",
"totalAmount" : 105.00,
"card" : {
"created" : "2018-05-12T14:02:00",
"brand" : "American Express",
"expMonth" : 2,
"expYear" : 2022,
"last4" : "0005",
"new" : false,
"links" : [ ],
"content" : [ ],
"links" : [ ]
},
"shippingAddress" : {
"modified" : "2018-05-12T14:02:00",
"created" : "2018-05-12T14:02:00",
"streetAddress" : "test",
"country" : "Netherlands",
"city" : "test",
"state" : "test",
"postalCode" : "test",
"new" : false,
"links" : [ ],
"content" : [ ],
"links" : [ ]
},
"billingAddress" : {
"modified" : "2018-05-12T14:02:00",
"created" : "2018-05-12T14:02:00",
"streetAddress" : "test",
"country" : "Netherlands",
"city" : "test",
"state" : "test",
"postalCode" : "test",
"new" : false,
"links" : [ ],
"content" : [ ],
"links" : [ ]
},
"oneAddress" : true,
"new" : false
} ]
此响应不包含items
我也需要从响应中获取的字段,即使有与任何订单相关联的项目。问题是什么?为什么上面引用的字段不包含在响应中?
谢谢
编辑
我尝试在OrderDetailEntity
以下字段中添加:
@OneToOne
@JoinColumn(name = "address_id")
private AddressEntity address;
然后正确序列化:
curl -X GET "http://localhost:8080/users/1/orders/2f8254e6-b04a-4fb0-baae-cb27fcd11a87"
[ {
"quantity" : 1,
"totalAmount" : 10.99,
"address" : {
"streetAddress" : "aa",
"country" : "Netherlands",
"city" : "aa",
"state" : "a",
"postalCode" : "a",
"modified" : "2018-05-12T18:49:48",
"created" : "2018-05-12T18:49:48",
"new" : false,
"links" : [ ],
"content" : [ ],
"links" : [ ]
},
"id" : 8,
"new" : false
但是 ProductEntity 没有序列化。以下是两个实体。我无法理解其中的区别。也许 ProductEntity 包含其他关联(而不是 AddressEntity),这可能会以某种方式影响序列化?
产品实体
@Table(name = "product")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PUBLIC) @AllArgsConstructor
public @Entity class ProductEntity extends AbstractPersistable<Long> {
private static final long serialVersionUID = -5077959382034660336L;
@NotEmpty
@Column(name = "product_name", length = 254)
private String name;
@NotEmpty
@Column(name = "product_description", length = 254)
private String description;
@Digits(integer = 12, fraction = 2)
@Column(name = "product_price")
@Range(min = 0, message = "The price must be greater or equals to 0.")
private BigDecimal price;
@NotEmpty
@Column(name = "image_url", length = 254)
private String imageUrl;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "product_category_id")
@JsonBackReference
@JsonIgnore
private CategoryEntity category;
@OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@BatchSize(size = 10)
@OrderBy
private SortedSet<ProductThumbnailEntity> thumbnails;
public ProductEntity(Long id) {
this.setId(id);
}
public ProductEntity(String name, String description, BigDecimal price) {
this.name = name;
this.description = description;
this.price = price;
}
}
地址实体
@Table(name = "address")
@Getter @Setter
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public @Entity class AddressEntity extends AbstractEntity<Long> {
private static final long serialVersionUID = 1544232699919709073L;
@Size(max = 254)@Column(name = "street_address")
private String streetAddress;
@Size(max = 50)
private String country;
@Size(max = 40)
private String city;
@Size(max = 100)
private String state;
@Size(max = 16) @Column(name = "postal_code")
private String postalCode;
}
解决方案
推荐阅读
- php - 如何显示 id 等于 1,2,3,4 的所有记录
- macos - Logstash /usr/local/etc/logstash/conf.d/ 安装后文件夹不存在
- powershell - 将文件复制到工作站上的所有用户,其中文件夹具有固定到用户的唯一代码
- jasper-reports - 如何计算页面详细信息带跨越的数量?
- azure - 执行重试逻辑后显示角色分配已存在错误
- r - 如何通过从复选框组中选择状态以交互方式并排从 UI 绘制图形?
- java - 创建没有实体的spring存储库
- javascript - 如何使用 !不混淆?
- sql-server - 新手:为 SQL Server 2017 创建 dockerfile
- c++ - 了解获取非静态成员地址以形成指向成员函数的指针的错误?