我正在使用 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。
如何解决这个问题?预先感谢您!
最佳答案
如果不查看正在加载/查询实体的代码,几乎不可能找出提取问题所在。那么您能否将其添加到您的问题中?
同时,至少有一些事情可以改进,以获得更清晰的实体和更快的代码,也许这也可以帮助解决问题。
首先,您使用冗余配置,以及重新创建默认值的相应注释。
我假设是 lombok你正在使用什么,对吗?您可以删除两个实体中字段上的 @Getter
和 @Setter
注释,并在类级别添加一次,以避免在每个字段上进行声明,但由于您是使用 @Data
你根本不需要它。与 @toString
相同,@Data
是所有这些(以及更多)的便捷注释。
@Data
的 JavaDoc 说:
Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
然后,尽管订单实体上的 @Table(name="\"order\"")
是必需的,因为 order 是某些 DBMS 中的保留字,但 @Table(购物车实体上的 name="cart")
是默认值。
接下来,我不建议对集合进行延迟初始化,因为与每次访问之前检查 null 时造成的损失相比,这样做通常没有任何好处。只需在声明中初始化它,您就不必再关心处理 null
了。除此之外,您应该考虑使用 Set 而不是购物车列表(这样您就不会出现重复项)。
还要考虑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;
}
关于java - 当结果为列表时,JPA @OneToMany 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43001491/