我面临一个烦人的问题,我认为这真的很愚蠢。 我正在使用带有JPA和Hibernate的H2数据库。 这是我在ScheduleService.class上的save方法:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public int save(Schedule sched) {
try {
scheduleRepository.save(sched);
} catch(Exception e) {...}
}
句子" scheduleRepository.save(sched)"抛出以下异常:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["UK_4R97H1MMVBOG9TD05OH9FKL16_INDEX_5 ON PUBLIC.SCHEDULE(CHANNEL, PROGRAMME, START, END) VALUES ( /* key:65574 */ null, TIMESTAMP '2015-09-15 17:00:00.0', null, TIMESTAMP '2015-09-15 16:40:00.0', 3, 13)"; SQL statement:
insert into schedule (channel, end, programme, published, start, idSched) values (?, ?, ?, ?, ?, ?) [23505-175]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
并在输出控制台上打印以下消息:
Unique index or primary key violation: "UK_4R97H1MMVBOG9TD05OH9FKL16_INDEX_5 ON PUBLIC.SCHEDULE(CHANNEL, PROGRAMME, START, END) VALUES ( /* key:65574 */ null, TIMESTAMP '2015-09-15 17:00:00.0', null, TIMESTAMP '2015-09-15 16:40:00.0', 3, 13)"; SQL statement:
insert into schedule (channel, end, programme, published, start, idSched) values (?, ?, ?, ?, ?, ?) [23505-175]
我已在Schedule实体中删除了 @UniqueConstraint 注释,以确保它不是唯一的约束问题。 错误仍然存在,因此必须由主键冲突引起。 这就是我如何定义Schedule实体的主键:
@Id
@Column(name = "idSched", nullable = false)
@GeneratedValue(strategy = GenerationType.TABLE)
protected Long idSched;
它应该为表中插入的每一行分配一个新的唯一idSched字段,对吗?
导致异常的问题是什么?
谢谢。
更新
根据Bohuslav的建议,我已将主键声明改为:
@Id
@TableGenerator(
name="scheduleGen",
table="schedule_sequence_table",
pkColumnValue="idSched",
allocationSize=1)
@GeneratedValue(strategy = GenerationType.TABLE, generator="scheduleGen")
@Column(name = "idSched", nullable = false)
protected Long idSched;
目前似乎工作正常。
更新2 :基于Sreenath评论:
我只生成一次表(它们作为磁盘上的文件保存)。实际上,在计划表上有一个唯一的键约束。但是,由于它抛出了异常,我删除了约束并删除了数据库文件,以确保问题不在唯一约束中,而是在主键中。即使没有独特的约束和全新的数据库,例外仍然存在,所以我带来了@TableGenerator解决方案。显然,这解决了这个问题。 但后来我再次设置了我的唯一约束,删除了数据库文件,以便可以重新生成表,并启动和停止应用程序几次。 现在问题又来了。 这是我唯一的约束:
@Table(uniqueConstraints={@UniqueConstraint(columnNames = {"channel", "programme", "start", "end"})})
@Entity(name = "schedule")
public class Schedule { ...}
当然,在我保存实体之前,我会检查是否有任何其他实体具有与我添加的实体相同的唯一成员:
Schedule schedIn = schedRep.findOneByChannelAndProgrammeAndStartAndEnd(
sched.getChannel(), sched.getProgramme(), sched.getStart(), sched.getEnd());
// Check if there exists any schedule with the same {channel, programme, start, end} values
if (schedIn == null) {
// If not, then save it
schedRep.save(sched);
}
方法schedRep.findOneByChannelAndProgrammeAndStartAndEnd()由JPA自动生成。这很奇怪,该查询无法找到具有相同{channel,program,start,end}值的任何计划,但是当我尝试保存它们时,违反了唯一约束。
那么问题可能出在哪里?