문제

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

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), 그러나 데이터베이스가 허용하지 않는다는 예외가 발생합니다. null 에 대한 값 TIMESTAMP 디자인에 의해 그렇지 않은 열.

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

나는 이전에 순수한 최대 절전 모드에서 작동하기 위해 이것을 얻었지만, 감각이 JPA로 전환 되었으며이 열이 데이터베이스 측면에서 생성 될 것이라고 생각하는 방법을 알지 못했습니다. JPA 지속성 계층으로 최대 절전 모드를 사용하고 있습니다.

도움이 되었습니까?

해결책

코드를 변경하여 문제를 해결했습니다

@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를 사용하고 있습니다.

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

이것은 나를 위해 효과가있었습니다.더 많은 정보

마지막으로 행이 수정 된 경우에만 관심이있는 경우 JPA2.0 및 MySQL 5.5.10을 사용 하여이 작업이 잘 작동합니다. MySQL은 첫 번째 삽입시 타임 스탬프를 생성하며 매번 업데이트가 행으로 호출됩니다. (참고 : 업데이트가 실제로 변경되었는지 여부를 걱정하면 문제가됩니다).

이 예제의 "타임 스탬프"열은 "마지막 터치"열과 같습니다 .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;
}

(참고 : @version은 Entity 클래스에서 속성 유형이 "날짜"인 MySQL "DateTime"열에서 작동하지 않습니다. 날짜는 밀리 초까지 값을 생성했지만 MySQL은 밀리 초를 저장하지 않았기 때문입니다. , 데이터베이스에있는 것과 "첨부 된"엔티티를 비교했을 때 버전 번호가 다른 것으로 생각했습니다)

타임 스탬프에 관한 MySQL 매뉴얼에서 :

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

나는 모든 데이터베이스에 자동 업데이트 타임 스탬프 (예 : 우편둥이)가 있다고 생각하지 않습니다. 그래서 나는이 필드를 내 코드의 어느 곳에서나 수동으로 업데이트하기로 결정했습니다. 이것은 모든 데이터베이스에서 작동합니다.

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

트리거를 사용해야 할 이유가 있지만 대부분의 프로젝트에서는이 중 하나가 아닙니다. 트리거는 특정 데이터베이스 구현에 더 깊이 파고 들었습니다.

MySQL 5.6.28 (Ubuntu 15.10, OpenJDK 64 비트 1.8.0_66)는 매우 용서하는 것 같습니다.

@Column(name="LastTouched")

MySQL 5.7.9 (Centos 6, OpenJDK 64 비트 1.8.0_72) 만

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

아니다:

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

내 다른 시스템 정보 (두 환경 모두 동일)

  • 최대 절전 모드-엔티티 관리자 5.0.2
  • 최대 절전 모드 검증기 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`
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top