java - 使用组合 PrimaryKey 更新 JPA 实体导致重复输入错误
问题描述
当我尝试使用 spring JpaRepository 多次并行存储相同的实体时,我得到一个 Duplicate entry for key PRIMARY
。TestEntity 由两个经常更改的值组成,而 TestEntityId 保持不变。这个想法是使用 save 方法根据 EmbeddedId 更新 TestEntity,因为我不确定数据库中是否已经存在 TestEntity。
如果对于同一个 EmbeddedId 经常发生这种情况,我会很快收到 Duplicate entry 错误。我还可以在单元测试中重现该行为。
当我运行测试时,出现异常: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));
...
}
我已经尝试在表上添加事务或不同的锁以及其他声明组合主键的方式。
如果您对如何解决此问题有任何想法,那就太好了。
解决方案
问题是您要创建 100 个具有相同主键的实体,而不是使用i
来增加它们。
推荐阅读
- linux - sed 用空格和特殊字符替换字符串
- vue.js - Kendo Grid Wrapper 中的复选框选择
- reactjs - 如何仅使用 babel 7 转换 node_modules 文件夹?
- android - Android Studio:共享设备开发
- logging - 在 JBoss 服务器的控制台上禁用打印 JAVA_OPTS
- sqlite - 如何在 SQLite 中存储唯一的类实例?
- azure-cosmosdb - Cosmos DB SQL API:过滤具有空嵌套对象的文档
- regex - 如何匹配包含 unicode 字符的完整字符串?
- numpy - 避免将掩码数组元素格式化为“0.00”
- c++builder - 检查显示???在 Rad Studio 10.3.2 中