Spring Data JPA + Oracle Trigger 将 ID 递增两次
Spring Data JPA + Oracle Trigger increments the ID twice
我使用以下技术堆栈:
- spring-boot-starter-data-jpa
- 用于连接池的 HikariCP
- 甲骨文数据库
我的实际代码与此类似。
/// My trigger looks like this
CREATE OR REPLACE TRIGGER FILE_BRI
BEFORE INSERT
ON FILE
FOR EACH ROW
BEGIN
SELECT FILE_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
///
public class FILE implements Serializable {
@Id
@SequenceGenerator(
name = "FILE_SEQ",
sequenceName = "FILE_SEQ",
allocationSize = 1)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "FILE_SEQ"
)
private long id;
}
public class ServiceA () {
@Transactional(propagation = REQUIRES_NEW, isolation = READ_COMMITTED)
public File insertFile() {
// Below line returns the inserted File object with ID as '58496'
return fileRepository.save(file)
}
@Transactional(propagation = REQUIRES_NEW, isolation = READ_COMMITTED)
public AccessControl insertAccessControl() {
// Below line results in 'SQLIntegrityConstraintViolationException' (full error at the bottom of this post)
return accessControlRepository.save(accessControlFile)
}
}
Public class FileProcessor() {
ServiceA serviceA;
public void someMethod() {
// insert the file and get the inserted record
File insertedFile = serviceA.insertFile(file);
// get the ID from the inserted file and make another insert into another table
serviceA.insertAccessControl(insertedFile.getId()); // inserted file ID is '58496'
}
}
这是我的调查:
当我在 table "FILE" 中验证插入记录的 ID 是 '58497' 时,但是 repository.save()
return 编辑了一个不同的值。
当我在 table "ACCESS_CONTROL_FILE" 上使用 FILE_ID
作为 '58496' 进行第二次插入时,会导致以下错误,因为 ID 为 '58496' 的文件不存在。
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("DB_OWNER"."ACCESS_CONTROL_FILE"."FILE_ID")
我很困惑为什么 repository.save()
return 与数据库中实际插入的 ID(ID=58497) 不同的 ID(即 ID=58496)!
我已经调查了所有可以在互联网上找到的与 'Propagation and Isolation' 有关的选项。
如评论中所述,问题似乎是由数据库触发器引起的。禁用触发器让 JPA 管理 ID 生成。
我使用以下技术堆栈:
- spring-boot-starter-data-jpa
- 用于连接池的 HikariCP
- 甲骨文数据库
我的实际代码与此类似。
/// My trigger looks like this
CREATE OR REPLACE TRIGGER FILE_BRI
BEFORE INSERT
ON FILE
FOR EACH ROW
BEGIN
SELECT FILE_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
///
public class FILE implements Serializable {
@Id
@SequenceGenerator(
name = "FILE_SEQ",
sequenceName = "FILE_SEQ",
allocationSize = 1)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "FILE_SEQ"
)
private long id;
}
public class ServiceA () {
@Transactional(propagation = REQUIRES_NEW, isolation = READ_COMMITTED)
public File insertFile() {
// Below line returns the inserted File object with ID as '58496'
return fileRepository.save(file)
}
@Transactional(propagation = REQUIRES_NEW, isolation = READ_COMMITTED)
public AccessControl insertAccessControl() {
// Below line results in 'SQLIntegrityConstraintViolationException' (full error at the bottom of this post)
return accessControlRepository.save(accessControlFile)
}
}
Public class FileProcessor() {
ServiceA serviceA;
public void someMethod() {
// insert the file and get the inserted record
File insertedFile = serviceA.insertFile(file);
// get the ID from the inserted file and make another insert into another table
serviceA.insertAccessControl(insertedFile.getId()); // inserted file ID is '58496'
}
}
这是我的调查:
当我在 table "FILE" 中验证插入记录的 ID 是 '58497' 时,但是 repository.save()
return 编辑了一个不同的值。
当我在 table "ACCESS_CONTROL_FILE" 上使用 FILE_ID
作为 '58496' 进行第二次插入时,会导致以下错误,因为 ID 为 '58496' 的文件不存在。
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("DB_OWNER"."ACCESS_CONTROL_FILE"."FILE_ID")
我很困惑为什么 repository.save()
return 与数据库中实际插入的 ID(ID=58497) 不同的 ID(即 ID=58496)!
我已经调查了所有可以在互联网上找到的与 'Propagation and Isolation' 有关的选项。
如评论中所述,问题似乎是由数据库触发器引起的。禁用触发器让 JPA 管理 ID 生成。