Home > Blockchain >  hibernate FetchType.LAZY fetching 0 record even the records being inserted
hibernate FetchType.LAZY fetching 0 record even the records being inserted

Time:09-17

The FetchType.LAZY is not working under the unit testing and showing 0 records

The line below showing 0 records log.info("Starting Lazy Search size ==>" setLazy.size());

The line below showing 1k records being inserted

There are one parent (StockEntity) and one child (StockDailyRecordEntity)

Total StockDailyRecordEntity Inserted ----->1000

package repo;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.app.advance.entity.StockDailyRecordEntity;
import com.app.advance.entity.StockEntity;
import com.app.advance.repo.StockDailyRecordRepo;
import com.app.advance.repo.StockRepo;

import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class)
@Slf4j
@SpringBootTest

public class StockRepoPerformance {

    @Autowired
    StockRepo stockRepo;

    @Autowired
    StockDailyRecordRepo stockDailyReportRepo;

    @Test
    public void testPerformanceInsert() {
        StockEntity stockEntity = new StockEntity();
        stockEntity.setStockCode("Code");
        stockEntity.setStockName(new Date().toString());
        stockRepo.save(stockEntity);
        for (int i = 0; i < 1000; i  ) {

            StockDailyRecordEntity stockDailyRecordEntity = new StockDailyRecordEntity();
            stockDailyRecordEntity.setStock(stockEntity);
            stockDailyRecordEntity.setDesc(new Date().toString());
            Set<StockDailyRecordEntity> stockDailyRecords = new HashSet<StockDailyRecordEntity>();
            stockDailyRecords.add(stockDailyRecordEntity);
            stockDailyReportRepo.save(stockDailyRecordEntity);

        }
        log.info("Total StockDailyRecordEntity Inserted ----->"   stockDailyReportRepo.findAll().size());
        stockRepo.save(stockEntity);
        log.info("Starting Lazy Search");
        Set<StockDailyRecordEntity> setLazy = stockEntity.getStockDailyRecords();
        log.info("Starting Lazy Search size ==>"   setLazy.size());

        log.info("Starting Eager Search");
        log.info("testPerformanceInsert ends");
    }
}

package com.app.advance.entity;

import static javax.persistence.GenerationType.IDENTITY;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import lombok.Getter;
import lombok.Setter;

// https://mkyong.com/hibernate/cascade-jpa-hibernate-annotation-common-mistake/

@Entity
@Table(name = "trx_stock")
@Getter
@Setter
public class StockEntity implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 4174876690328458921L;

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "STOCK_ID", unique = true, nullable = false)
    private Integer stockId;

    @Column(name = "STOCK_CODE", nullable = false, length = 10)
    private String stockCode;

    @Column(name = "STOCK_NAME", nullable = false, length = 200)
    private String stockName;
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock", orphanRemoval = true)
    @Cascade({CascadeType.ALL})
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<StockDailyRecordEntity> stockDailyRecords = new HashSet<StockDailyRecordEntity>();
    
    //@OneToMany(fetch = FetchType.EAGER, mappedBy = "stock", orphanRemoval = true)
    //@Cascade({CascadeType.ALL})
    //@OnDelete(action = OnDeleteAction.CASCADE)
    //private Set<StockDailyRecordEntity> stockDailyRecordsEager = new HashSet<StockDailyRecordEntity>();
}

package com.app.advance.entity;

import static javax.persistence.GenerationType.IDENTITY;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import lombok.Getter;
import lombok.Setter;

@Entity
@Table(name = "trx_stock_daily_record")
@Getter
@Setter
public class StockDailyRecordEntity implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -7102491956593238645L;

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "RECORD_ID", unique = true, nullable = false)
    private Integer recordId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "STOCK_ID", nullable = false)
    private StockEntity stock;
    
    @Column(name = "STOCK_DESC", length = 200)
    private String desc;

}

CodePudding user response:

In the following code you are inserting the newly created stockDailyRecordEntity into a set... then throwing away the set:

Set<StockDailyRecordEntity> stockDailyRecords = new HashSet<StockDailyRecordEntity>();
stockDailyRecords.add(stockDailyRecordEntity);
stockDailyReportRepo.save(stockDailyRecordEntity);

You could do:

stockEntity.setStockDailyRecords(stockDailyRecords);

But you don't need to create a new set, just add to the collection of the stock entity, i.e. replace the 3 lines above with:

stockEntity.getStockDailyRecords().add(stockDailyRecordEntity);

Why are the stock daily records being saved though? - Because you are saving them - stockDailyReportRepo.save(stockDailyRecordEntity);

Why is setLazy.size() zero? - Because you have added nothing to this collection. When persisting a new entity, JPA will not tweak its collections, i.e. read them from the database. If you were to fetch this entity from the database, not reuse the one you created in the beginning of the method, this method should work.

  • Related