如何在Spring Data JPA中保存列表时处理DataIntegrityVilolationException?

时间:2015-09-21 09:00:03

标签: spring hibernate spring-data-jpa

我在Spring引导应用程序中使用Spring Data JPA,使用MYSQL。我在那里保存一个对字段有唯一约束的实体列表。在实体列表中,由于唯一约束,有一个实体将抛出DataIntegrityViolationException。我注意到在这种情况下没有任何实体持久存在,即使是那些没有违反唯一约束的实体。 在这种情况下,理想的方法是什么,以便那些不违反唯一的实体持久存在? 当然,我可以迭代列表并逐个保存。实际上,这就是SimpleJpaRepository在底层所做的事情。

@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;
}

我的代码 - 实体:

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

    private String name;
    //getter setters 
}

存储库:

public interface SampleContentRepository extends JpaRepository<SampleContent, Serializable>{

}

JUnit测试:

@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!");
    }
}

表中已有一个名为“Roy”的实体。因此,整个交易失败并且@Transactional回滚。

1 个答案:

答案 0 :(得分:0)

我认为您可以使用后续步骤:

  1. 将现有实体从DB加载到Set
  2. 根据equals
  3. 覆盖hashCodename方法
  4. 给你Set::addAll打电话(或者只是逐个添加)
  5. Set保存到DB
  6. 也许它不是最理想的,因为迫使你进行select *查询。但我认为将数据逐个保存到数据库更有效。

    根据this article,您可以使用名称作为您的业务密钥,这有很多好处。