How to handle DataIntegrityVilolationException while saving a list in Spring Data JPA?

别等时光非礼了梦想. 提交于 2021-01-28 22:38:46

问题


I am using Spring Data JPA in a Spring Boot Application, with MYSQL. There I am saving a list of entities with unique constraint over a field. Out of the list of entities, there is one entity that will throw DataIntegrityViolationException due to the unique constraint. I noticed that none of the entities get persisted in that case, even those that does not violate the unique constraint. What should be the ideal approach in this case so that those entities which do not violate the unique get persisted ? Of course I can iterate the list and save them one by one. In fact that is what SimpleJpaRepository is doing underneath.

@Transactional
public <S extends T> List<S> save(Iterable<S> entities) {

    List<S> result = new ArrayList<S>();

    if (entities == null) {
        return result;
    }

    for (S entity : entities) {
        result.add(save(entity));
    }

    return result;
}

My code - Entity :

@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "name" }, name = "uq_name"))
public class SampleContent {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    //getter setters 
}

Repository :

public interface SampleContentRepository extends JpaRepository<SampleContent, Serializable>{

}

JUnit test :

@Test
public void testCreate(){
    List<SampleContent> sampleContentList =  new ArrayList<>();
    SampleContent sampleContent1 = new SampleContent();
    sampleContent1.setName("dd");
    SampleContent sampleContent2 = new SampleContent();
    sampleContent2.setName("Roy");
    SampleContent sampleContent3 = new SampleContent();
    sampleContent3.setName("xx");
    sampleContentList.add(sampleContent1);
    sampleContentList.add(sampleContent2);
    sampleContentList.add(sampleContent3);
    try{
        this.sampleContentRepository.save(sampleContentList);
    }catch(DataIntegrityViolationException e){
        System.err.println("constraint violation!");
    }
}

There is an entity with name "Roy" already present in the table. So, the entire transaction fails and @Transactional rolls back.


回答1:


I think you can use next steps:

  1. Load existing entities from DB into Set
  2. Override equals and hashCode methods based on name
  3. call Set::addAll you antities (or just add them one by one)
  4. save that Set to DB

Maybe it's suboptimal because forces you to make select * query. But I think it's much more effective then saving entities one by one to DB.

Accotding to this article you can use name as your business key, which has lots of benefits.



来源:https://stackoverflow.com/questions/32691128/how-to-handle-dataintegrityvilolationexception-while-saving-a-list-in-spring-dat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!