2012-12-06 4 views
3

MySql으로 타임 스탬프를 만드는 데 문제가 있습니다. @DatabaseField 정의에서 특정 DataType.TIME_STAMP 항목을 사용하지 않는 측면에서 제안 사항 here을 따랐습니다.MySQL에서 ORMLite 문제로 타임 스탬프 생성

내 현재 @DatabaseField은 다음과 같다 : 표에

@DatabaseField(format="yyyy-MM-dd HH:mm:ss", defaultValue="CURRENT_TIMESTAMP") 
private Timestamp updatedAt; 

그래도 점점 오류가 생성 : 그래서 그것은 형식 정의하지 않고, 형식 정의를 무시하는 것 같다

Unable to create table because of [Problems parsing default date 
string 'CURRENT_TIMESTAMP' using 'yyyy-MM-dd HH:mm:ss.SSSSSS'] 

, 나는 아직 도착 이 오류 :

Unable to create table because of [Problems parsing default date 
string 'CURRENT_TIMESTAMP' using 'yyyy-MM-dd HH:mm:ss.SSSSSS'] 

데이터 유형을 지정하려고했습니다. c DATE_TIME에 매달려 있습니다. (아직 Timestamp를 사용하지 않고 단지 CURRENT_TIMESTAMP으로 작동하는 DATE_TIME을 만드는 것 외에는 조합을 찾지 못했습니다.)

과거에 수동으로 테이블을 업데이트했기 때문에 정말 고생했지만 이제는 숫자가 늘어나고 ORMLite에서 테이블 생성 옵션을 사용하여 프로세스를 완전히 자동화하고 싶습니다. 나중에 스키마를 수동으로 엉망으로 만든다.

모든 포인터는이 작업을 수행하는 방법에 매우 환영받을 것입니다.

+0

는 메시지가있을 수 있습니다를 문제 여기 안토니. 문제는''CURRENT_TIMESTAMP ''가 변환 패턴과 일치하지 않기 때문에 기본값으로 사용할 수 없다는 것입니다. 어떻게 든 특수한 경우가 필요해. 각 DB 유형이이를 다르게 수행하기 때문에 이것은 고통스런 일이 될 것입니다. – Gray

+0

와우! 초고속 응답 그레이 주셔서 감사합니다. 문제를 이해하고 사용자가 해결할 수있는 방법이 있습니까? MySQL 버전을 Postres에 넣으면 테이블 작성이 자연스럽게 실패합니다. 그래서 그것은 내가 의미하는 바를 본다면, 계급 설계 문제가 아니라 기반 구조 문제입니다. 아마도 timestamp에 대해서만 defaultValue 필드에 입력 된 것을 수락하면됩니까? 권리를 얻기위한 사용자의 책임. 그게 너에게 효과가 있니? – Anthony

+0

그게 맞는 해결책일지도 몰라. _perfect_ 솔루션은 추상 데이터베이스 유형에 일종의 Timestamp 유효성 검사기를 갖는 것입니다. :-) 나는 실제로 문자열 파싱을해야한다는 것에 조금 놀랐다. 오늘 나중에 보겠습니다. – Gray

답변

3

지금은 Timestamp 필드에서 작동하지 않는 @DatabaseFiled(version = true)을 사용하는 것을 제외하면이 작업을 수행하는 방법이 보이지 않습니다. 이 트렁크에 해결할되었으며 4.46에서 작업됩니다

http://ormlite.com/docs/version-field

그것이 4.45에서 타임 스탬프 필드와 함께 작동하도록하는 것입니다 꽤 각 불구하고. extends TimeStampType이 필요하며 다음 메소드를 무시하십시오. 자세한 내용은이 답변의 하단을 참조하십시오

@Override 
public Object moveToNextValue(Object currentValue) { 
    long newVal = System.currentTimeMillis(); 
    if (currentValue == null) { 
     return new java.sql.Timestamp(newVal); 
    } else if (newVal == ((java.sql.Timestamp) currentValue).getTime()) { 
     return new java.sql.Timestamp(newVal + 1L); 
    } else { 
     return new java.sql.Timestamp(newVal); 
    } 
} 

는 다음과 같이 필드를 지정 :

@DatabaseField(persisterClass = LocalCurrentTimeStampType.class, version = true) 
java.sql.Timestamp timestamp; 

[날짜를 만들뿐만되지 않은 다른 업데이트에 대한 다음 작품. ]]

이것은 사소한 것이었지만 마침내 트렁크의 최신 버전을 사용하여이 작업을 수행 할 수있는 방법을 알았습니다. 4.46에서는 읽기 전용 인 필드에 @DatabaseField(readOnly = true)에 대한 지원을 추가 할 예정입니다. 이를 통해 다음과 같이 말할 수 있습니다 :

@DatabaseField(defaultValue = "CURRENT_TIMESTAMP()", readOnly = true) 
java.sql.Timestamp timestamp; 

읽기 전용 필드는 생성되거나 업데이트되지 않으며 쿼리에서만 반환됩니다. 문제는 CURRENT_TIMESTAMP()의 유효성을 검사 할 때 TimeStampType이 예외를 throw한다는 것입니다.

public class LocalCurrentTimeStampType extends TimeStampType { 
    private static final LocalCurrentTimeStampType singleton = 
     new LocalCurrentTimeStampType(); 
    private String defaultStr; 
    public LocalCurrentTimeStampType() { 
     super(SqlType.DATE, new Class<?>[] { java.sql.Timestamp.class }); 
    } 
    public static LocalCurrentTimeStampType getSingleton() { 
     return singleton; 
    } 
    @Override 
    public boolean isEscapedDefaultValue() { 
     if ("CURRENT_TIMESTAMP()".equals(defaultStr)) { 
      return false; 
     } else { 
      return super.isEscapedDefaultValue(); 
     } 
    } 
    @Override 
    public Object parseDefaultString(FieldType fieldType, String defaultStr) throws SQLException { 
     this.defaultStr = defaultStr; 
     if ("CURRENT_TIMESTAMP()".equals(defaultStr)) { 
      return defaultStr; 
     } else { 
      return super.parseDefaultString(fieldType, defaultStr); 
     } 
    } 
} 

이 그런 다음 필드 정의가된다 :이 문제를 해결하려면 사용자 정의 persister를 정의 할 필요가

@DatabaseField(persisterClass = LocalCurrentTimeStampType.class, 
    defaultValue = "CURRENT_TIMESTAMP()", readOnly = true) 
java.sql.Timestamp timestamp; 

당신은 GitHub의 코드에서 최신 버전을 얻을 수 있습니다 : https://github.com/j256/ormlite-core

+0

고마워 그레이 - 기술적 인 제약을 이해하지만 최소한 테이블을 많이 편집하는 것은 절약된다. – Anthony

+0

자체 greated 테이블에서 ORMlite를 사용할 때 이상한 동작이 발생했습니다. 'cdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP' 컬럼으로 테이블을 생성하고 객체 정의에서'@DatabaseField (readOnly = true)'로 표시하지 않으면 테이블을 직접 생성하더라도 기본 타임 스탬프를 설정하지 않습니다. INSERT 문을 실행할 때 ORMlite 명시 적으로 null 값을 설정합니까? – Phidelux