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.