Isaac Fiset
Isaac Fiset

Reputation: 107

Spring hibernate no commits until the end

so I have a problem and I am kind of new with spring. So basically I want that nothing is commited until the end of "retrieveAndSaveInformationFromBac()". For the moment if an exception is throw some changes will be commited. Here is the code:

public void retrieveAndSaveInformationFromBac() throws ClientWSBacException {
logger.info("Start BATCH BAC");
BatchContextManager.useBatchSchemaForCurrentThread();
Map<ClasseId, Classe> mapClasses = new HashMap<>();
try {
  logger.info("Deleting existant table...");

  deleteAllTables();
  ClientWSBac client = new ClientWSBac(productService);
  List<ModeleBac> listModeleBacToSave = new ArrayList<>();
  for(VehiculeType type : VehiculeType.values()){
    logger.info("Saving the type : "+ type);
    Map<BacFileKey, List<ModeleBac>> mapModeleBac = client.retrieveAndSaveAllFromBac(type, mapClasses);

    listModeleBacToSave = new ArrayList<>();
    for(List<ModeleBac> listModeleBac : mapModeleBac.values()) {
      for(ModeleBac modele : listModeleBac) {


        if(modele.getNivsBac().size() > 0){
          checkEnDescriprions(modele);
          listModeleBacToSave.add(modele);
        }
      }
      if(listModeleBacToSave.size()> 500){
          saveListModeleBac(listModeleBacToSave);
      }

    }
    saveListModeleBac(listModeleBacToSave);
  }
  saveClasseAndTypeCarrosserie(mapClasses);
  logger.info("END OF THE BATCH");
  switchDataSourcesAfterBatch();
} catch (Exception e) {
  logger.error("Error during importation", e);
  throw new ClientWSBacException("Error during importation.Stopping the process....");
}finally{
  BatchContextManager.clear();
}}

And this is where I "save" my info:

@Transactional
private void saveListModeleBac(List<ModeleBac> listModeleBac){
long startTime = System.nanoTime();
  try{
    modeleBacDAO.save(listModeleBac);
  } catch (Exception e){
    e.printStackTrace();
    logger.error("Error during the save of the informations..");
    throw e;
 }
long endTime = System.nanoTime();
long duration = ((endTime - startTime)/1000000000);
logger.debug("Number of insert : " + String.valueOf(listModeleBac.size())+ " in " + String.valueOf(duration) + " seconds" );}

And here is where I delete the table:

@Transactional
 private void deleteAllTables(){
if(databaseMode.equals(DatabaseMode.H2)){
  modeleBacDAO.deleteAllModeleBac();
  classeDAO.deleteAllInBatch();
  typeCarrosserieDAO.deleteAllInBatch();
}else{
  dataSourceUtils.callStoredProcVideTable(currentDBSchemaResolver.resolveCurrentTenantIdentifier());
}}

Upvotes: 1

Views: 149

Answers (2)

Gab
Gab

Reputation: 8332

@Transactional can't work on private method because it's applied using an aspect (using dynamic proxies)

Basically you want the retrieveAndSaveInformationFromBac() to be a single unit of work, ie. a transaction.

So annotate it with @Transactional.

Upvotes: 2

Leviand
Leviand

Reputation: 2805

Since you are using Hibernate , you can handle this by a property:

<property name="hibernate.connection.autocommit">false</property>

Then you can commit with the transaction, like

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//do stuff and then
tx.commit();

Upvotes: 0

Related Questions