Как работать с PersistentBag Hibernate, не подчиняющегося списку, равному контракту? - PullRequest
2 голосов
/ 10 апреля 2019

У меня есть объект со списком:

@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 имеют одинаковые элементы.И, как и ожидалось, список элементов возвращается из метода getItemsIfSame.

Но когда я запускаю свое приложение, и оно проходит два заказа с одинаковыми элементами, возвращается ноль.После отладки и исследования я обнаружил, что фактический тип, возвращаемый методом Order getItems, равен org.hibernate.collection.internal.PersistentBag.Его документация гласит:

Bag не соблюдает API-интерфейс сбора данных и выполняет сравнение экземпляров JVM для выполнения операций равенства.Семантика нарушена, так как не нужно инициализировать коллекцию для простой операции equals ().

И, подтверждая в исходном коде, он просто вызывает метод equals Object (даже если он реализуетList).

Полагаю, я мог бы скопировать все элементы из PersistentBag в ArrayList и затем сравнить, но иногда я проверяю равенство для объекта, у которого есть какое-то вложенное свойство со списком.Есть ли лучший способ проверить равенство списков между сущностями?

...