문제 상황
2025-12-22T15:03:38.959 WARN --- [main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "
alter table if exists timeseries.sensor_data add column id bigint generated by default as identity" via JDBC [오류: 하위 테이블에 재귀적으로 식별 칼럼을 추가할 수 는 없음]
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table if exists timeseries.sensor_data add column id bigint generated by default as identity" via JDBC
[오류: 하위 테이블에 재귀적으로 식별 칼럼을 추가할 수는 없음]
TimescaleDB Hypertable은 내부적으로 여러 Chunk(하위 테이블)로 분할된다.
Hibernate가 id 컬럼을 추가하려 하는데, Hypertable은 이미 생성된 상태라서 구조 변경이 불가능했다.
해결 방법
ID 컬럼을 변경한다.
TimescaleDB에서는 timestamp를 Primary Key로 사용하기 때문이다.
Q. 같은 시간에 여러 센서 데이터가 들어오면?
A. 그래서 복합 키로 ID를 재구성 해야 한다. timestamp + sensor_id
SensorDataId
package com.autonics.scada.timeseries.entity;
import jakarta.persistence.Embeddable;
import lombok.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;
@Embeddable
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class SensorDataId implements Serializable {
private LocalDateTime timestamp;
private String sensorId;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SensorDataId that = (SensorDataId) o;
return Objects.equals(timestamp, that.timestamp) &&
Objects.equals(sensorId, that.sensorId);
}
@Override
public int hashCode() {
return Objects.hash(timestamp, sensorId);
}
}
SensorData
package com.autonics.scada.timeseries.entity;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "sensor_data", schema = "timeseries")
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class SensorData {
@EmbeddedId
private SensorDataId id;
@Column(name = "temperature")
private Double temperature;
@Column(name = "pressure")
private Double pressure;
@Column(name = "value")
private Double value;
@PrePersist
protected void onCreate() {
if (this.id == null || this.id.getTimestamp() == null) {
this.id = SensorDataId.builder()
.timestamp(LocalDateTime.now())
.sensorId(this.id != null ? this.id.getSensorId() : null)
.build();
}
}
public String getSensorId() {
return id != null ? id.getSensorId() : null;
}
public LocalDateTime getTimestamp() {
return id != null ? id.getTimestamp() : null;
}
}'Dev > Database' 카테고리의 다른 글
| [DB] RDB vs. NoSQL (0) | 2024.03.11 |
|---|