JPA保存方法上的主键违规

时间:2015-09-13 17:20:38

标签: spring hibernate jpa h2

我面临一个烦人的问题,我认为这真的很愚蠢。 我正在使用带有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}值的任何计划,但是当我尝试保存它们时,违反了唯一约束。

那么问题可能出在哪里?

0 个答案:

没有答案