【发布时间】:2019-10-09 16:09:49
【问题描述】:
当我尝试使用 spring JpaRepository 并行存储同一个实体多次时,我得到一个重复条目,用于键 PRIMARY。 TestEntity 由两个值组成,它们经常变化,而 TestEntityId 保持不变。这个想法是使用 save 方法根据 EmbeddedId 更新 TestEntity,因为我不确定 TestEntity 是否已经存在于数据库中。
如果对于同一个 EmbeddedId 经常发生这种情况,我会很快收到重复条目错误。我还可以在单元测试中重现该行为。
运行测试时出现异常:java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1-2-prov' for key 'PRIMARY'
@Entity
public class TestEntity {
@EmbeddedId
private TestEntityId testEntityId;
@Column
private String value1;
@Column
private String value2;
...
}
@Embeddable
public class TestEntityId implements Serializable {
private double lat;
private double lng;
private String prov;
...
}
@Repository
public interface TestEntityRepository extends JpaRepository<TestEntity, TestEntityId> {
// Empty
}
测试用例
@Test
public void testStoreSameEntryMultipleTimes() {
LongStream.range(1L, 100L).boxed().parallel()
.map((i) -> new TestEntityId(1.0, 2.0, "prov"))
.map((te) -> new TestEntity(te , "value1", "value2"))
.forEach((e) -> testEntityRepository.save(e));
...
}
我已经尝试在表上添加事务或不同的锁以及其他方式来声明组合主键。
如果您对如何解决此问题有任何想法,那就太好了。
【问题讨论】:
-
测试浮点是否相等是乞求得到灾难性的舍入错误。
-
如果你不并行遍历流,你会得到相同的结果吗?
-
不,它工作正常,完成后我在 DB 中有 1 个条目。不幸的是,它后来从并行运行的进程中调用,这是我在重现它之前第一次看到问题的地方。
标签: java database jpa spring-data-jpa primary-key