3

BIGINT列を使用してタイムスタンプを格納する既存のMySQLデータベースにアクセスする必要があります。

create table mytable (created bigint);

今は整数ではなくインスタンスを使用することを好むjava.util.Dateのでjava.time.Instant、Hibernateに値を直接変換させようとしています。残念ながら、Hibernateは、次のように注釈が付けられている場合、列を認識しません。

@Column(name = "created")
private Date created;

またはこのように:

@Column(name = "created")
@Temporal(TemporalType.TIMESTAMP)
private Calendar created;

これは将来、のようなものを返します2017-07-01T04:14:00+02:00BIGINTゲッターやセッターで列を変換する必要がないように、Hibernateで列を適切に変換するにはどうすればよいですか?

4

1 に答える 1

1

HibernateのTemporalType.TIMESTAMPマップjava.sql.Timestamp。コンストラクターはTimestamp、エポックからのミリ秒数であるLong値を取ります。データベースの値は、エポックからの秒数であるUnixタイムスタンプとして保存されます。

UnixTimestampTypeミリ秒ではなく秒でインスタンスを作成するを作成しましたDate

public class UnixTimestampType extends AbstractSingleColumnStandardBasicType<Date> implements IdentifierType<Date>, LiteralType<Date> {
    private static final long serialVersionUID = 1L;
    public static final UnixTimestampType INSTANCE = new UnixTimestampType();

    public UnixTimestampType() {
        super(UnixTimestampTypeDescriptor.INSTANCE, JdbcDateTypeDescriptor.INSTANCE);
    }

    @Override
    public String getName() {
        return "date";
    }

    @Override
    public String[] getRegistrationKeys() {
        return new String[] { getName(), java.sql.Date.class.getName() };
    }

    @Override
    public String objectToSQLString(Date value, Dialect dialect) throws Exception {
        final java.sql.Date jdbcDate = java.sql.Date.class.isInstance(value) ? (java.sql.Date) value : new java.sql.Date(value.getTime());
        return StringType.INSTANCE.objectToSQLString(jdbcDate.toString(), dialect);
    }

    @Override
    public Date stringToObject(String xml) {
        return fromString(xml);
    }
}

public class UnixTimestampTypeDescriptor implements SqlTypeDescriptor {
    private static final long serialVersionUID = 1L;
    public static final UnixTimestampTypeDescriptor INSTANCE = new UnixTimestampTypeDescriptor();

    @Override
    public int getSqlType() {
        return Types.INTEGER;
    }

    @Override
    public boolean canBeRemapped() {
        return true;
    }

    @Override
    public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicBinder<X>(javaTypeDescriptor, this) {
            @Override
            protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
                Date date = javaTypeDescriptor.unwrap(value, Date.class, options);
                date.setTime(date.getTime() / 1000);
                st.setDate(index, date);
            }
        };
    }

    @Override
    public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicExtractor<X>(javaTypeDescriptor, this) {
            @Override
            protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
                Date date = new Date(rs.getLong(name) * 1000);
                return javaTypeDescriptor.wrap(date, options);
            }
        };
    }
}
于 2012-12-07T15:42:07.743 に答える