当结果为列表时,JPA @OneToMany不起作用



我正在使用JPA,Spring boot。 当我获取包含购物车项目的订单时,使用@OneToMany注释。 我的域名代码如下。

次序:

@Data
@Entity
@Table(name=""order"")
@ToString
public class Order {
@Id
@GeneratedValue
@Getter @Setter
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name="order_id")
@Getter @Setter
private List<Cart> carts;
public void addCart(Cart cart) {
if (this.carts == null) {
carts = new ArrayList<Cart>();
}
carts.add(cart);
}
}

车:

@Data
@Entity
@Table(name="cart")
@ToString
public class Cart {
@Id
@GeneratedValue
@Getter @Setter
@Column(name="id")
private Long id;
@Column(name = "order_id")
@Getter @Setter
private Long orderId;
}

当我只获取一个订单时,这非常有效,但当我获取两个以上的订单时,这不起作用。我的意思是,当我只获取一个订单时,购物车字段的大小为 1 或更多,但当我获取两个或更多订单时,购物车字段的大小为 0。

如何解决这个问题?提前谢谢你!

如果不看到正在加载/查询实体的代码,几乎不可能找出获取问题是什么。那么,您能否将其添加到您的问题中?

同时,至少有一些东西可以改进,以获得更干净的实体和更快的代码,也许这也可以帮助解决问题。

首先,您使用的是冗余配置,即重新创建默认值的相应注释。

我假设你正在使用的是龙目岛,对吧?您可以删除两个实体中字段上的@Getter@Setter注释,并在类级别添加一次,以避免在每个字段上声明,但由于您使用的是@Data因此根本不需要它。与@toString相同,@Data是所有这些(以及更多)的方便注释。

@Data的JavaDoc 说:

等效于 {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}。

然后,尽管由于订单在某些 DBMS 中是保留字,因此需要订单实体上的@Table(name=""order""),但购物车实体上的@Table(name="cart")是默认值。

接下来,我不建议延迟初始化集合,因为与每次访问前检查 null 时造成的损失相比,这样做没有任何好处。只需在声明中初始化它,您将永远不必再关心处理null。除此之外,您应该考虑使用"设置"而不是购物车列表(这样您就不会有重复项)。

还要考虑FetchType因为EAGER仅在使用分离的实体并希望在每种情况下初始化关系时才有用。LAZY@OneToMany的默认值,应首选。

您已经改进的一件事是@JoinColumn,这将阻止 Hibernate(我厚颜无耻地假设您正在使用 Hibernate)创建一个连接表。但更重要的是考虑将@OneToMany变成另一边的@ManyToOne或使其双向。这将在读取(它还可以防止连接表,因此需要更少的连接,可以更快地索引)和写入时间(由父端管理的关系)上获得一些性能。

那么你怎么看这个:

@Data
@Entity
@Table(name=""order"")
public class Order {
@Id
@GeneratedValue
private Long id;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Cart> carts = new HashSet<>();
}

而这个:

@Data
@Entity
public class Cart {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Order order;
}

Order class:

public class Order {
@Id
@GeneratedValue
@Getter @Setter
private Long id;
@OneToMany(mappedBy="orderId" fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@Getter @Setter
private Set<Cart> carts;
}

推车类:

public class Cart {
@Id
@GeneratedValue
@Getter @Setter
@Column(name="id")
private Long id;
@ManyToOne
@Getter @Setter
private Order orderId;
}

例如:JPA 一对多和多对一关系

我只是写它来改变。 我希望它会起作用

最新更新