[英]JPA @OneToMany is not working when result is list
我正在使用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。
我怎么解决这个问题? 先感谢您!
订单类别:
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;
}
我只是写它来改变。 我希望它会起作用
在不查看正在加载/查询实体的代码的情况下,几乎不可能找出提取问题。 因此,您可以将其添加到您的问题中吗?
同时,至少可以改进一些内容以拥有更简洁的实体和更快的代码,也许这也可以帮助您解决问题。
首先,您使用的是冗余配置,您将使用其各自的注释重新创建默认值。
我认为您使用的是龙目岛 ,对吧? 您可以在两个实体的字段中都删除@Getter
和@Setter
批注,并在类级别添加一次,以避免在每个字段中都声明,但是由于使用@Data
,因此根本不需要它。 同样的, @toString
, @Data
是所有它的一个方便的注解(多一点)。
@Data
的JavaDoc说:
等效于{@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}。
然后,尽管由于在某些DBMS中订单是保留字,所以需要订单实体上的@Table(name="\\"order\\"")
,但默认情况下,购物车实体上的@Table(name="cart")
是默认的。
接下来,我不建议延迟集合的延迟初始化,因为与在每次访问之前检查null时造成的代价相比,这样做通常没有任何好处。 只需在声明中对其进行初始化,就不必担心再次处理null
了。 除此之外,您应该考虑使用Set代替购物车的List(这样您就不会重复)。
还请考虑FetchType
因为EAGER
仅在使用分离的实体并希望在每种情况下都初始化关系时才有用。 LAZY
是@OneToMany
的默认值,应首选。
@JoinColumn
是您已经改进的一个东西,它将防止Hibernate(我@JoinColumn
假设您正在使用Hibernate)创建@JoinColumn
表。 但是更重要的是考虑将@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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.