I have a csv file of data which has altogether 100 000 records. I am iterating over the records and trying to update 5 tables for each record. Here is the sample data:
EAN Code,Site,Genric Material,Material,Sap Ean Code,Style,Color,Size,MRP,Gender,EAN Code,Season,Collection,BRAND,Color revision,Category (L5),Category (L6)
123456789,6001,000000000061000102,000000061000102001,61000102001,03/BE100,SC/TG,L/112 cm,850.00,MENS,123456789,AW12,Colors,XXXXXX,RD/TG,Tee Shirt,Graphic
The five tables that will be updating for each iteration are as follows:
- Master
- MasterDescription
- Attributes
- AttributeValues
- AssociationTable
The relationship between the above mentioned tables are as follows:
Master M-M AttributeValues
Master M-1 MatserDescription
Master M-M Attributes
Attributes 1-M AttributeValues
Here is the code that I have to save the CSV data into 5 tables in a single session using batch technique:
Service class
@Service
public class EanService{
@AutoWired
public EanRepository eanrepository;
// Method that saves data from CSV to DataBase
@Transactional
public void saveEANMasterData1(BufferedReader br, String userName,
List<EanAttributes> attributes, String eanMasterName,String description) {
int i =1;
EanMasterDiscription eanDes = new EanMasterDiscription();
User user = userRepository.findUserByUsername(userName);
EanMasterDiscription deciption = null;
eanDes.setDescription(description);
eanDes.setMasterName(eanMasterName);
eanDes.setDate(new Timestamp(Calendar.getInstance()
.getTimeInMillis()));
String line;
try {
List<Ean> eans = new ArrayList<Ean>();
// iterating over each record in the CSV and saving the data into DB
while (((line = br.readLine()) != null)) {
String[] cols = line.split(",");
// Style Keeping Unit
Ean ean = new Ean();
for(EanAttributes attr : attributes){
EanAttributeValues eanAttributeValues = new EanAttributeValues();
if(attr.getAttrInferredType().equalsIgnoreCase("EAN")){
ean.setEAN(cols[attr.getAttributeOrder()]);
}else if(attr.getAttrInferredType().equalsIgnoreCase("Season")){
ean.setSeason(cols[attr.getAttributeOrder()]);
}else {
if(attr.getAttrInferredType().equalsIgnoreCase("Attribute")){
EanAttributes eanAttr = eanrepository.loadAttrsListByAttName(attr.getAttributeName());
if(eanAttr == null){
eanAttributeValues.setAttributeValue(cols[attr.getAttributeOrder()]);
eanAttributeValues.setEanAttributes(attr);
ean.getEanAttributeValues().add(eanAttributeValues);
ean.getEanAttributes().add(attr);
attr.getEan().add(ean);
}else{
ean.getEanAttributes().add(eanAttr);
eanAttr.getEan().add(ean);
if(eanrepository.isAttributeValueAvailable(cols[attr.getAttributeOrder()])){
eanAttributeValues.setAttributeValue(cols[attr.getAttributeOrder()]);
eanAttributeValues.setEanAttributes(eanAttr);
ean.getEanAttributeValues().add(eanAttributeValues);
}else{
EanAttributeValues values = eanrepository.loadDataByAttrValue(cols[attr.getAttributeOrder()]);
ean.getEanAttributeValues().add(values);
values.getEan().add(ean);
}
}
eanAttributeValues.getEan().add(ean);
}
}
}
if(!eanrepository.isEanMasterNameAvailable(eanMasterName)){
EanMasterDiscription eanMasterDes = eanrepository.loadDataByMasterName(eanMasterName);
ean.setEanMasterDesciption(eanMasterDes);
}else{
ean.setEanMasterDesciption(eanDes);
}
ean.setUser(user);
if(eanrepository.isEanWithSeasonAvailable(ean.getEAN(),ean.getSeason())){
// Persisting Ean; I think there is some problem with this method
eanrepository.saveEanData(ean,i);
}else{
System.out.println("************ EAN ALREADY EXIST ******************** ");
}
i++;
}
} catch (NumberFormatException | IOException e) {
e.printStackTrace();
}
}
}
Repository class
@Repository
public class EanRepository{
@PersistanceContext
EntityManager em;
public void saveEanData(Ean ean , int recordNum){
em.merge(ean);
if(recordNum % 50 == 0){
em.flush();
em.clear();
// em.getEntityManagerFactory().getCache().evictAll();
}
}
}
But this is taking too much time (nearly 10hrs) to finish saving all the 100 000 records. How can we reduce the time and what I am missing?