У меня есть основное приложение SpringBoot 2.1.5.RELEASE. Использование Spring Initializer, JPA, встроенного Tomcat, механизма шаблонов Thymeleaf и пакета в качестве исполняемого файла JAR.
У меня есть этот класс домена:
@Entity
@Table(name="t_purchase")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Purchase implements Serializable {
public Purchase() {
}
public Purchase(Shop shop) {
super();
this.shop = shop;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty("id")
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = “shop_id")
@JsonIgnore
Shop shop;
…
}
а также
@Entity
@Table(name = “t_shop")
public class Shop implements Serializable {
public Shop(String name) {
this.name = name;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty("id")
private Long id;
@JsonProperty("name")
private String name;
@OneToMany(mappedBy = “shop", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JsonIgnore
private Set<Purchase> purchases = new HashSet<Purchase>();
…
}
и этот метод в хранилище:
@Query("select shop from Shop shop left join shop.purchases where shop.id = ?1")
Shop shopPurchases (Long shopId);
Затем я создал этот метод Junit:
@Test
public void testFindByShopIdWithPurchases () {
Shop shop = new Shop ("Shop_NAME");
shopService.save(shop);
Purchase purchase1 = new Purchase(shop);
Purchase purchase2 = new Purchase(shop);
shop.getPurchases().add(purchase1);
shop.getPurchases().add(purchase2);
shopService.save(shop);
Shop shopWithPurchases = shopService.findByShopIdWithPurchases(shop.getId());
assertEquals (2, shopWithPurchases.getPurchases().size());
}
Но это терпит неудачу, потому что это возвращает 1 покупку вместо 2
Всего 1 ответ
Если вы переопределяете equals для сущностей со сгенерированным идентификатором, вам нужно обработать случай, когда оба идентификатора равны нулю. В противном случае HashSet будет рассматривать новые права как равные и будет хранить только одно.
Вы можете использовать значение по умолчанию в этом случае:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Purchase other = (Purchase) obj;
if(this.id == null) {
if(other.id == null) {
return super.equals(other);
}
return false;
}
return this.id.equals(other.id);
}