2017-02-15 9 views
2

Я пытаюсь заполнить свою БД большим количеством тестовых данных, поэтому я написал CommandLineRunner для сохранения около 2 тыс. Сущностей.spring boot jpa - генерировать и сохранять данные теста

It Work's - но наступает конец FOREVER (5-10 минут) - Я справляюсь с этим неправильно?

@Component 
public class DbSeederTest implements CommandLineRunner { 

    @Autowired 
    FirstRepo firstRepo; 
    @Autowired 
    SecondRepo secondRepo; 
    @Autowired 
    ThirdRepo thirdRepo; 

    private List<FirstEnt> firstList = new ArrayList<>(); 
    private List<SecondEnt> secondList = new ArrayList<>(); 
    private List<ThirdEnt> thirdList = new ArrayList<>(); 


    private void generateTestData() { 
      // generate alot of entities, and add them to the Lists 
    } 

    @Override 
    public void run(String... args) throws Exception { 

     System.out.println("saving ents..."); 

     generateTestData(); 

     try { 

      firstRepo.save(firstList); 
      secondRepo.save(secondList); 
      thirdRepo.save(thirdList); 

     } catch(Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 
+0

Я не знаю, почему это занимает слишком много времени, но вы можете уменьшить время, используя концепцию потока. Поскольку данные уже заполняются после 'generateTestData();', поэтому теперь вызывайте каждый метод сохранения repo в другой поток. – SachinSarawgi

ответ

0

Вы можете попробовать и воспользоваться функцией массовой вставки.

Существует зимуют свойство, которое можно определить как одно из свойств в Hibernate SessionFactory:

<property name="jdbc.batch_size">250</property> 

С этой партии установки вы должны иметь выход как:

insert into Table(id , name) values (1, 'na1') , (2, 'na2') ,(3, 'na3')..

вместо

insert into Table(id , name) values (1, 'na1'); 
insert into Table(id , name) values (2, 'na2'); 
insert into Table(id , name) values (3, 'na3'); 

В репозитории сохранить методы вы бы сохраняющиеся около 250 (вы должны сделать некоторые испытания, что это сладкое пятно точки зрения производительности в вашем приложении) объекты .. а затем промывка для обеспечения максимальной производительности до тех пор, пока все данные не будут сохранены:

public void save(List<Item> itemList){ 
    for (int i=0; i<itemList.size(); i++) { 
     session.save(itemList.get(i)); 

     if (i % 250 == 0) { //250, same as the JDBC batch size 
      //flush a batch of inserts and release memory: 
      session.flush(); 
      session.clear(); 
     } 
    } 
} 
0

Вы можете уменьшить время, затрачиваемое на использование концепции Threading.

Перед вызовом save метод всех репо у вас есть данные после звонка generateTestData();.

Так изменить код немного

Thread thread1 = new Thread(()->firstRepo.save(firstList)); 
Thread thread2 = new Thread(()->secondRepo.save(secondList)); 
Thread thread3 = new Thread(()->thirdRepo.save(thirdList)); 
thread1.start(); 
thread2.start(); 
thread3.start(); 

Thread метод запуска является переопределить с помощью функции Java 8 вы можете сделать это в Java 7 следующим образом:

Thread thread1 = new Thread(new Runnable() { 

    @Override 
    public void run() { 
     firstRepo.save(firstList); 

    } 
}); 

Надеется, что это помогает.