spazzola
spazzola

Reputation: 319

How to fix the most common LazyInitializationException - Hibernate JPA

I'm struggling with LazyInitializationException. I've read so far literally every article about that, but unfortunately I didn't find solution for my problem. Many of those solutions using EntityManager or things which I don't using. I'm connecting with my DB via JPA.

I've got couple of entities, but the problem is just with two of them: Order and OrderDetails. When I get from DB object Order, and then I'll try to do order.getOrderDetails() then I gettin following error:

Exception:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.tradesystem.order.Order.orderDetails, could not initialize proxy - no Session

but it works the other way around: from OrderDetails object I can get Order by objectDetail.getOrder() . What's more: I can't use Eager loading due to fact that I'm using it in another entity.

Here's my Order class:

@Entity
@Data
@Table(name = "orders")
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_id")
private Long id;

private LocalDate date;

@OneToMany(mappedBy = "order")
private List<OrderDetails> orderDetails;

@ManyToOne
@JoinColumn(name = "buyer_fk")
private Buyer buyer;

@ManyToOne
@JoinColumn(name = "supplier_fk")
private Supplier supplier;
}

OrderDao:

@Repository("orderDao")
public interface OrderDao extends JpaRepository<Order, Long> {

@Query(value = "SELECT * FROM orders " +
        "WHERE MONTH(orders.date) = ?1 AND YEAR(orders.date) = ?2",
        nativeQuery = true)
List<Order> getMonthOrders(int month, int year);
}

and OrderDetails:

@Entity
@Data
@Table(name = "orderDetails")
public class OrderDetails {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_details_id")
private Long id;

private BigDecimal quantity;

private BigDecimal sum;

@ManyToOne
@JoinColumn(name = "order_fk")
private Order order;

@ManyToOne
@JoinColumn(name = "product_fk")
private Product productType;

@OneToOne
@JoinColumn(name = "order_comment_fk")
private OrderComment orderComment;
}

Relationship that finished with @Many is Lazy loaded by default, so why it doesn't load my OrderDetails when I doing .getOrderDetails() ?

I will be really gratefull for any help! PS. I'm begginer, so if I didn't explain something enough good, don't hestitate to make some questions.

Upvotes: 0

Views: 683

Answers (2)

spazzola
spazzola

Reputation: 319

I have solved that problem. I was running everything in CommandLineRunner. Lazy Exception disappeared when I started making tests insted of "trying something" in main class.

My main class looked like:

 @Bean
 public CommandLineRunner bookDemo(OrderDao orderDao, PriceDao priceDao, ProductDao productDao,
                                   OrderService orderService, InvoiceDao invoiceDao, InvoiceService invoiceService) {
                                   OrderService orderService, InvoiceDao     invoiceDao, InvoiceService invoiceService,
                                   ReportService reportService) {
     return (args) -> {

         List<Order> orders = orderDao.findByBuyerId(1L);

         for (Order order : orders) {
             orderService.payForOrde(order);
         }

Upvotes: 0

Christian Beikov
Christian Beikov

Reputation: 16452

Use this

@Repository("orderDao")
public interface OrderDao extends JpaRepository<Order, Long> {

    @Query(value = "SELECT orders FROM Order orders LEFT JOIN FETCH orders.orderDetails " +
        "WHERE MONTH(orders.date) = ?1 AND YEAR(orders.date) = ?2")
    List<Order> getMonthOrders(int month, int year);
}

Upvotes: 1

Related Questions