@OneToMany Spring Boot 2.1.5.RELEASE 中的 Spring Data JPA 没有获取所有数据

Posted

技术标签:

【中文标题】@OneToMany Spring Boot 2.1.5.RELEASE 中的 Spring Data JPA 没有获取所有数据【英文标题】:@OneToMany Spring Data JPA in SpringBoot 2.1.5.RELEASE Does not get all data 【发布时间】:2019-10-03 09:07:53 【问题描述】:

我有一个基本的 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】:

如果您为具有生成 id 的实体覆盖 equals,您需要处理两个 id 均为空的情况。否则 HashSet 会将新实体视为平等,并且只会存储一个。

在这种情况下你可以使用默认的equals:

@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);

【讨论】:

以上是关于@OneToMany Spring Boot 2.1.5.RELEASE 中的 Spring Data JPA 没有获取所有数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 和 PostgreSQL 中使用 OneToMany 关系

使用 JPA 的 Spring Boot OnetoMany

Spring boot JPA - 没有嵌套对象的 JSON 与 OneToMany 关系

Spring Boot中@OneToMany与@ManyToOne几个需要注意的问题

在 Spring Boot 中使用生成的 ID 持久化 OneToMany 实体

如何在 Spring Boot JPA 中的 OneToMany 中为孩子获取 Null 值