【发布时间】:2021-05-12 08:34:31
【问题描述】:
在现有答案中搜索没有得到有效结果。所以这是我找不到原因的错误。
我有一个实体类MeteoRecord 和DayDegree定义如下:
@Getter
@Setter
@Entity
public class MeteoRecord extends AbstractEntity {
@Temporal(TemporalType.DATE)
Date date;
...
//other attributes
}
@Entity
@Getter
@Setter
public class DayDegree extends AbstractEntity {
@ManyToOne
@JoinColumn(name = "meteo_record_id")
private MeteoRecord meteoRecord;
...
//other attributes
}
所有实体都扩展AbstractEntity类:
@MappedSuperclass
@Getter
@Setter
public abstract class AbstractEntity implements Serializable {
@Access(AccessType.PROPERTY)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "DATCRE")
public Date datcre;
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "DATMOD")
public Date datmod;
}
保存新的MeteoRecord 时如下:
Optional<MeteoRecord> meteoByDate = meteoRecordRepository.findByDate(dateAsDate);
MeteoRecord meteoRecord;
if (meteoByDate.isPresent()) {
meteoRecord = meteoByDate.get();
} else {
meteoRecord = new MeteoRecord();
meteoRecord.setDate(dateAsDate);
}
MeteoRecord savedMeteoRecord = meteoRecordRepository.save(meteoRecord);
...
它引发了错误:
rg.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "meteo_record_pkey"
Detail: Key (id)=(1680) already exists.
`MeteoRepositiry 只是扩展了 `JPARepository:
@Repository
public interface MeteoRecordRepository extends JpaRepository<MeteoRecord, Long> {
...
Optional<MeteoRecord> findByDate(Date date);
}
我激活了更多日志以查看 SQL 查询,但没有看到创建新 MeteoRecord 的其他查询,也没有在其他地方插入 DayDegree 记录:
11:33:55.664 [http-nio-8080-exec-1] DEBUG org.hibernate.SQL -
select
meteorecor0_.id as id1_33_,
meteorecor0_.datcre as datcre2_33_,
meteorecor0_.datmod as datmod3_33_,
meteorecor0_.date as date4_33_,
meteorecor0_.degree_day_15 as degree_d5_33_,
meteorecor0_.degree_day_15_eq as degree_d6_33_,
meteorecor0_.station as station7_33_,
meteorecor0_.temp_avg as temp_avg8_33_,
meteorecor0_.temp_avg_eq as temp_avg9_33_
from
meteo_record meteorecor0_
where
meteorecor0_.date=?
Hibernate:
select
meteorecor0_.id as id1_33_,
meteorecor0_.datcre as datcre2_33_,
meteorecor0_.datmod as datmod3_33_,
meteorecor0_.date as date4_33_,
meteorecor0_.degree_day_15 as degree_d5_33_,
meteorecor0_.degree_day_15_eq as degree_d6_33_,
meteorecor0_.station as station7_33_,
meteorecor0_.temp_avg as temp_avg8_33_,
meteorecor0_.temp_avg_eq as temp_avg9_33_
from
meteo_record meteorecor0_
where
meteorecor0_.date=?
11:33:55.677 [http-nio-8080-exec-1] DEBUG o.s.d.r.c.s.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
11:33:55.679 [http-nio-8080-exec-1] DEBUG o.s.orm.jpa.JpaTransactionManager - Found thread-bound EntityManager [SessionImpl(1454087429<open>)] for JPA transaction
11:33:55.680 [http-nio-8080-exec-1] DEBUG o.s.orm.jpa.JpaTransactionManager - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
11:33:55.680 [http-nio-8080-exec-1] DEBUG o.h.e.t.internal.TransactionImpl - On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
11:33:55.680 [http-nio-8080-exec-1] DEBUG o.h.e.t.internal.TransactionImpl - begin
11:33:55.681 [http-nio-8080-exec-1] DEBUG o.s.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@27864a10]
11:33:55.696 [http-nio-8080-exec-1] DEBUG org.hibernate.engine.spi.ActionQueue - Executing identity-insert immediately
11:33:55.703 [http-nio-8080-exec-1] DEBUG org.hibernate.SQL -
insert
into
meteo_record
(datcre, datmod, date, degree_day_15, degree_day_15_eq, station, temp_avg, temp_avg_eq)
values
(?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
meteo_record
(datcre, datmod, date, degree_day_15, degree_day_15_eq, station, temp_avg, temp_avg_eq)
values
(?, ?, ?, ?, ?, ?, ?, ?)
11:33:55.732 [http-nio-8080-exec-1] DEBUG o.h.e.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "meteo_record_pkey"
Detail: Key (id)=(1681) already exists.
我错过了什么?我的印象是这是因为DayDegree 实体中定义的关系,但没有看到任何查询或使用DayDegree 实体。
谢谢。
【问题讨论】:
-
您是否在一个事务中运行有问题的代码sn-p?
-
运行代码的服务类标注
@Transactional。 -
但是使用与否
@Transaction注解根本不会影响错误,不管有没有它都会发生。 -
看起来很奇怪,hibernate生成的sql中没有
id字段..你如何在MeteoRecord中定义它,它是如何在数据库中管理的? -
因为日志中有一个
Executing identity-insert immediately,我猜你正在使用GenerationType.IDENTITY,而SEQUENCE在PostgreSQL中更可取。无论如何,您确定数据库是一致的并且没有其他记录具有给定的 id?