Spring数据JPA+;Oracle触发器将ID增加两次
我使用以下技术堆栈:Spring数据JPA+;Oracle触发器将ID增加两次,oracle,hibernate,jpa,spring-data-jpa,database-trigger,Oracle,Hibernate,Jpa,Spring Data Jpa,Database Trigger,我使用以下技术堆栈: spring引导启动器数据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;
- spring引导启动器数据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'
}
}
这是我的调查:
当我验证表“FILE”中插入的记录的ID为“58497”时,repository.save()
返回了一个不同的值。
当我在ID为“58496”的表“ACCESS\u CONTROL\u FILE”上进行第二次插入时,由于ID为“58496”的文件不存在,因此会导致以下错误
原因:java.sql.SQLIntegrityConstraintViolationException:ORA-01400:无法在“DB\u OWNER”“ACCESS\u CONTROL\u FILE”“FILE\u ID”中插入NULL
我不明白为什么repository.save()
返回的ID(即ID=58496)与数据库中实际插入的ID(ID=58497)不同
我已经调查了互联网上所有与“传播和隔离”相关的选项。如评论中所述,似乎是数据库触发器导致了这个问题。禁用触发器以让JPA管理ID生成。看起来序列在数据库级别又增加了一次。你在db检查过你是否有一个触发器或序列在执行它吗?@jusermar10,很好,我没有考虑过。我在我的帖子中添加了这个特殊的触发器。看起来触发器试图为每一行创建一个唯一的主键。你能确认这是否属实吗?是的,这是问题的根源。如果您希望jpa处理序列生成,请禁用触发器我不想出于其他原因完全禁用/删除触发器,我在这里找到了一个替代解决方案,该解决方案基于尚未创建ID的条件抑制触发器。尽管如此,还是要感谢@jusermar10提供的指针。