It's nearly impossible to find out what the fetching problem is without seeing the code which is loading / querying your entities. So could you please add it to your question?
Meanwhile there are at least some things you could improve to have cleaner entities and faster code, maybe this also can help a little to hunt down the problem.
At first, you are using redundant configurations, respective annotations you are recreating the default values with.
I assume that is lombok what you are using, right? You could remove the @Getter
and @Setter
annotations on your fields in both entities and add it once on class level to avoid the declaration on every single field, but since you are using @Data
you don't need it at all. Same with @toString
, @Data
is a convenience annotations for all of it (and a little more).
The JavaDoc of @Data
says:
Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
Then, although the @Table(name="\"order\"")
on the order entity is needed because order is a reserved word in some DBMS, the @Table(name="cart")
on the cart entity is the default.
Up next, I would not recommend lazy initialization of collections, because in general there is no benefit to do that compared to the penalty it causes while checking for null before every access. Just initialize it within declaration and you will never have to care about handling null
again. Beside of that you should think about using a Set instead a List for the carts (so you will have no duplicates).
Also think about the FetchType
because EAGER
is only useful if you work with detached entities and want to initialize the relation in every case. LAZY
is the default for @OneToMany
and should be preferred.
A thing you already improved is the @JoinColumn
, that will prevent Hibernate (I brazenly assume you are using Hibernate) creating a join table. But even more important is thinking about turning the @OneToMany
into a @ManyToOne
on the other side or making it bidirectional. That would gain some performance on reading (it also prevents the join table so less joins are needed, faster indexing is possible) and writing time (relation managed by parent side).
So what do you think about this:
@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<>();
}
and this:
@Data
@Entity
public class Cart {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Order order;
}