我有一个包含列表的实体:
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="orderId", nullable=false)
private List<Item> items;
}
@Entity
@Data
public class Item {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@EqualsAndHashCode.Exclude
private Long id;
private String description;
}
我有一个服务,用于检查两个订单是否有相同的商品,如果有,则返回这些商品;否则返回null:
public List<Item> getItemsIfSame(Order order1, Order order2) {
if (order1.getItems() != null && order1.getItems().equals(order2.getItems())) {
return order1.getItems();
}
return null;
}
我有一个单元测试,其中order1和order2具有相同的items。并且从getItemsIfSame
方法返回了items列表。
但是当我运行应用程序并传递具有相同items的两个订单时,将返回null。经过调试和研究,我发现Order
方法getItems
返回的实际类型是org.hibernate.collection.internal.PersistentBag
。其文档如下:
Bag不尊重集合API,并进行JVM实例比较以执行equals操作。语义被打破,因为不必初始化一个集合即可进行简单的equals()操作。
通过查看源代码,我们可以确认它只调用Object
的 equals方法(即使它实现了List
)。
我想我可以从PersistentBag
复制所有元素到ArrayList
,然后进行比较,但有时我正在检查具有某些嵌套属性和列表的对象的相等性。是否有更好的方法来检查实体之间的列表相等性?