IT

TIMESTAMP 열을 ZonedDateTime JPA 엔티티 속성에 매핑하려면 어떻게 해야 합니까?

itgroup 2023. 1. 15. 17:04
반응형

TIMESTAMP 열을 ZonedDateTime JPA 엔티티 속성에 매핑하려면 어떻게 해야 합니까?

Spring data jpamariadb 최신버전과 MariaDB 10.3.16을 사용하고 있습니다.

+--- org.springframework.boot:spring-boot-starter-data-jpa -> 2.1.5.RELEASE
...
|    +--- org.springframework.boot:spring-boot-starter-jdbc:2.1.5.RELEASE
...
|    +--- org.hibernate:hibernate-core:5.3.10.Final

이것이 나의 엔티티입니다.

@Entity
@Data
@Table
@NoArgsConstructor
@AllArgsConstructor
public class Note {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer id;

    @Column
    private String gsn;

    @Column
    @Enumerated(EnumType.STRING)
    private NoteType type;

    @Column
    private String text;

    @Column
    private ZonedDateTime scheduleDt;

    @Column
    @CreationTimestamp
    private Instant createDt;

    @Column
    @UpdateTimestamp
    private ZonedDateTime updateDt;
}

엔티티를 유지하면 휴지 상태가 저장하려고 합니다.ZonedDateTime멤버를 DATETIME 열로 지정합니다.하지만 DATETIME 열 대신 TIMESTAMP 열을 사용하고 싶습니다.

이것은 DDL 생성입니다.로그에서 확인할 수 있습니다.

create table `note` (`id` integer not null, `create_dt` datetime,
    `gsn` varchar(255), `schedule_dt` datetime, `text` varchar(255),
    `type` varchar(255), `update_dt` datetime, primary key (`id`)) 
  engine=MyISAM

여기서create_dt,schedule_dt,update_dt로서 작성됩니다.datetime컬럼 타입, 내가 원하지 않는 것.(나도 MyISAM 싫어)

어떻게 하면 고칠 수 있죠?


코멘트가 ddl을 표현할 수 없기 때문에 추가됩니다.

columnDefinition 속성을 사용하는 경우 생성된 ddl은...

create table `note` (`id` integer not null, `create_dt` datetime,
    `gsn` varchar(255), `schedule_dt` datetime, `text` varchar(255),
    `type` varchar(255), `update_dt` `TIMESTAMP`, primary key (`id`)) 

engineISAM

TIMESTAMP 주위에 불필요한 ''가 있습니다.

JPA 2.2는 Java 8 Date/Time API 매핑을 지원하지만 다음 유형에 대해서만 지원합니다.

그러나 Hibernate는 다음과 같은 기능도 지원합니다.

저장 시ZonedDateTime, 다음Timestamp에 송신됩니다.PreparedStatement:

Timestamp.from( zonedDateTime.toInstant() )

그리고 데이터베이스에서 읽을 때ResultSet를 포함합니다.Timestamp로 변환됩니다.ZonedDateTime, 다음과 같이 합니다.

ts.toInstant().atZone( ZoneId.systemDefault() )

주의:ZoneId데이터베이스에 저장되지 않기 때문에 기본적으로는 를 사용하는 것이 좋습니다.LocalDateTime이 경우Timestamp변환이 적합하지 않습니다.

예를 들어 다음과 같은 엔티티가 있다고 가정합니다.

@Entity(name = "UserAccount")
@Table(name = "user_account")
public class UserAccount {

    @Id
    private Long id;

    @Column(name = "first_name", length = 50)
    private String firstName;

    @Column(name = "last_name", length = 50)
    private String lastName;

    @Column(name = "subscribed_on")
    private ZonedDateTime subscribedOn;

    //Getters and setters omitted for brevity
}

주의:subscribedOnattribute는ZonedDateTimeJava 오브젝트

지속할 때UserAccount:

UserAccount user = new UserAccount()
    .setId(1L)
    .setFirstName("Vlad")
    .setLastName("Mihalcea")
    .setSubscribedOn(
        LocalDateTime.of(
            2020, 5, 1,
            12, 30, 0
        ).atZone(ZoneId.systemDefault())
    );

entityManager.persist(user);

휴지 상태에서는 적절한 SQL INSERT 문이 생성됩니다.

INSERT INTO user_account (
    first_name, 
    last_name, 
    subscribed_on, 
    id
) 
VALUES (
    'Vlad', 
    'Mihalcea', 
    '2020-05-01 12:30:00.0', 
    1
)

를 취득할 때UserAccount엔티티, 우리는 볼 수 있습니다.ZonedDateTime데이터베이스로부터 올바르게 취득되고 있다.

UserAccount userAccount = entityManager.find(
    UserAccount.class, 1L
);

assertEquals(
    LocalDateTime.of(
        2020, 5, 1,
        12, 30, 0
    ).atZone(ZoneId.systemDefault()),
    userAccount.getSubscribedOn()
);

@Column 주석을 사용하여 열 유형을 정의할 수 있습니다.

@Column(columnDefinition="TIMESTAMP")  
@UpdateTimestamp
private ZonedDateTime updateDt;

언급URL : https://stackoverflow.com/questions/56647962/how-to-map-a-timestamp-column-to-a-zoneddatetime-jpa-entity-property

반응형