1

Edited: I think I found something: Insert after delete same transaction in Spring Data JPA

So maybe I've got what I want to know, but still more comments are welcomed!


A piece of code doesn't work as expected, the code want to save a list of data(they belongs to one 'person') to database, to avoid duplicate, it first delete all the existing data(of the 'person') and then save all provided data(there may be duplicates between old and new), detail steps is:

    1. List<TableStructure> entries = entryMapper.toTableStructure(dtos);
    2. entryDao.deleteAll(personObj.getId());
    3. entryDao.saveAll(entries);

the issue is that, if previous value to be deleted are [item1, item2] and new value to be saved are [item1, item3], after the code run, only item3 will be saved to database. The fix is simple, an expert switched the sequence a bit and then it works. new steps:

    1. entryDao.deleteAll(personObj.getId());
    2. List<TableStructure> entries = entryMapper.toTableStructure(dtos);
    3. entryDao.saveAll(entries);

The explanation from expert is:

After entryMapper.toTableStructure(), the data will be read from DB and gave > an ID, then the delete and create of the item(item1 as in example) will be merged together, which results in delete only.

It may sound reasonable but I still want to know the details, and what kind of problem this is? What should I learn to avoid this in the future? This should be a common problem but I failed to find previous threads, must be something wrong with the key words I provided, what should I search?

The entryMapper also read data from entryDao, and entryDao is like this:

    @org.springframework.stereotype.Repository
    public interface Dao extends                 
    Repository<TableStructure, Integer> {

        <S extends TableStructure> S save(S toSave);

        <S extends TableStructure> List<S> saveAll(Iterable<S> toSave);

        @Query(SqlQuery.GET_ARTIFACT_PROPERTIES)
        List<TableStructure> getData(Integer dataId);

        @Modifying
        @Query(SqlQuery.DELETE_ALL)
        void deleteAll(Integer personId);
    }
Blangero
  • 115
  • 1
  • 1
  • 10

0 Answers0