0

I have Spring Boot application in which I am reading CSV file and trying to save it in database.

Below is the main boot class.

@SpringBootApplication
@ComponentScan("com.abg.meter")
@PropertySource(ignoreResourceNotFound = false, value = "file:${user.home}/application.properties")
@EnableTransactionManagement
public class ABGExecution{

public static void main(String[] args) {
    SpringApplication.run(ABGExecution.class, args);
 }
}

Below is the CustomIdGenerator

public class CustomIdGenerator implements IdentifierGenerator {

@Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
    long i = 0;
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {
        connection = session.connection();
        statement = connection.createStatement();
        resultSet = statement.executeQuery("SELECT max(id) FROM public.sku_details");
        if (resultSet.next()) {
            i = resultSet.getLong(1);
            i = i + 1;
        }
    } catch (Exception e) {
        throw new HibernateException("Unable to generate Indetifier " + e.getMessage());
    }
    System.out.println("generated id is "+i);
    return i;
}
}

Below is my service method

@Transactional
public void saveCSVData(){
   for(int i=0; i<=rowCount; i==){
      skudao.save(skudetails);
   }
}

Whenever save method is called CustomIdGenerator is generating and id. For example it generated 5 as id. Once save method is called it does not persist entity immediately. Entity remain attached with session. That is why for next save CustomIdGenerator generates 5 as id again. So when I call save method again I am getting below exception.

org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session : [com.abg.meter.pojo.SkuDetails#5]; nested exception is org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.abg.meter.pojo.SkuDetails#5]
1
  • Why are you using a custom id generator rather than leaving it to the database to generate via a sequence or identity column? Even if you flush the changes immediately as suggested below, your code is not thread safe without additional synchronisation i.e. 2 threads could read the same max(id) before it has been updated. Commented Dec 6, 2019 at 15:05

1 Answer 1

0

You should call flush() on the session or entity manager to execute the insert statement.

Or you could run every save in its own transaction.

Otherwise the database will not be changed.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.