programing

데이터베이스에서 생성 할 JPA 타임 스탬프 열을 설정 하시겠습니까?

nasanasas 2021. 1. 7. 08:04
반응형

데이터베이스에서 생성 할 JPA 타임 스탬프 열을 설정 하시겠습니까?


내 SQL Server 2000 데이터베이스에는 기본값 / 바인딩으로 설정된 DATETIME이름 의 타임 스탬프 (데이터 형식이 아닌 함수) 열이 있습니다.lastTouchedgetdate()

Netbeans 6.5에서 생성 된 JPA 엔티티 클래스를 사용하고 있으며 내 코드에 있습니다.

@Basic(optional = false)
@Column(name = "LastTouched")
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

그러나 객체를 데이터베이스에 넣으려고 할 때

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.generic.Stuff.lastTouched

나는 설정을 설정하려고했습니다 @Basic에를 (optional = true),하지만 데이터베이스가 허용하지 않습니다라고 예외가 발생 nullTIMESTAMP이 설계하지 않는 열을.

ERROR JDBCExceptionReporter - Cannot insert the value NULL into column 'LastTouched', table 'DatabaseName.dbo.Stuff'; column does not allow nulls. INSERT fails.

이전에 순수 Hibernate에서 작동하도록했지만 JPA로 전환 한 것을 감지했으며이 열이 데이터베이스 측에서 생성 될 것이라고 가정하는 방법을 알지 못합니다. JPA 지속성 레이어로 여전히 Hibernate를 사용하고 있습니다.


코드를 다음과 같이 변경하여 문제를 해결했습니다.

@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

따라서 SQL 삽입을 생성 할 때 타임 스탬프 열이 무시됩니다. 이것이 최선의 방법인지 확실하지 않습니다. 피드백을 환영합니다.


나는 이것이 조금 늦었다는 것을 알고 있지만 타임 스탬프 열에 주석을 달아 성공했습니다.

@Column(name="timestamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

이는 CURRENT_DATE에서도 작동 CURRENT_TIME합니다. Oracle과 함께 JPA / Hibernate를 사용하고 있으므로 YMMV.


@Column(nullable = false, updatable = false)
@CreationTimestamp
private Date created_at;

이것은 나를 위해 일했습니다. 더 많은 정보


행이 마지막으로 수정 된 시간에만 관심이있는 경우 JPA2.0 및 MySQL 5.5.10을 사용하여 잘 작동합니다. MySQL은 첫 번째 삽입과 행에서 UPDATE가 호출 될 때마다 타임 스탬프를 생성합니다. (참고 : UPDATE가 실제로 변경했는지 여부를 신경 쓰면 문제가됩니다.)

이 예에서 "timestamp"열은 "last-touched"열과 같습니다 .x`

아래 코드는 낙관적 잠금을 위해 별도의 "버전"열을 사용합니다.

private long version;
private Date timeStamp

@Version
public long getVersion() {
    return version;
}

public void setVersion(long version) {
    this.version = version;
}

// columnDefinition could simply be = "TIMESTAMP", as the other settings are the MySQL default
@Column(name="timeStamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getTimeStamp() {
    return timeStamp;
}

public void setTimeStamp(Date timeStamp) {
    this.timeStamp = timeStamp;
}

(NOTE: @Version doesn't work on a MySQL "DATETIME" column, where the attribute type is "Date" in the Entity class. This was because Date was generating a value down to the millisecond, however MySQL was not storing the millisecond, so when it did a comparison between what was in the database, and the "attached" entity, it thought they had different version numbers)

From the MySQL manual regarding TIMESTAMP :

With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.

I do not think that every database has auto-update timestamps (e.g. Postgres). So I've decided to update this field manually everywhere in my code. This will work with every database:

thingy.setLastTouched(new Date());
HibernateUtil.save(thingy);

There are reasons to use triggers, but for most projects, this is not one of them. Triggers dig you even deeper into a specific database implementation.

MySQL 5.6.28 (Ubuntu 15.10, OpenJDK 64-Bit 1.8.0_66) seems to be very forgiving, not requiring anything beyond

@Column(name="LastTouched")

MySQL 5.7.9 (CentOS 6, OpenJDK 64-Bit 1.8.0_72) only works with

@Column(name="LastTouched", insertable=false, updatable=false)

not:

FAILED: removing @Temporal
FAILED: @Column(name="LastTouched", nullable=true)
FAILED: @Column(name="LastTouched", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")

My other system info (identical in both environments)

  • hibernate-entitymanager 5.0.2
  • hibernate-validator 5.2.2
  • mysql-connector-java 5.1.38

@Column(name = "LastTouched", insertable = false, updatable = false, columnDefinition = "TIMESTAMP default getdate()")
@Temporal(TemporalType.TIMESTAMP)
private Date LastTouched;`enter code here`

This worked for me:

@Column(name = "transactionCreatedDate", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

ReferenceURL : https://stackoverflow.com/questions/811845/setting-a-jpa-timestamp-column-to-be-generated-by-the-database

반응형