Такая функция поддерживается некоторыми провайдерами JPA , к сожалению, Eclipselink не является одним из них.
К счастью, пользовательский механизм преобразования атрибутов EclipseLink позволяет вам получить доступ к Session
во время преобразования, поэтому работает следующий обходной путь:
@Converter(name = "database-timestamp", converterClass = DatabaseTimestampFieldConverter.class)
@Entity
public class AuditedEntity {
@Id
@GeneratedValue
private Long id;
private String name;
...
@Convert("database-timestamp")
private Timestamp updatedDate;
@PreUpdate
protected void preUpdate() {
updatedDate = null; // needed to trigger the conversion; if you don't want the extra method here, use @EntityListeners instead
}
}
, где DatabaseTimestampFieldConverter
определяется как:
public class DatabaseTimestampFieldConverter implements Converter {
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
return session.executeQuery(new ValueReadQuery("SELECT CURRENT_TIMESTAMP"));
}
@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
return dataValue;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public void initialize(DatabaseMapping mapping, Session session) {
}
}
В качестве альтернативы, вы можете попробовать построить поверх пример аудита из документов . Однако он использует жестко закодированные имена столбцов базы данных, а не аннотации на уровне полей.
Конечно, использование механизмов, предоставляемых вашей базой данных (например, триггеры), вероятно, будет более эффективным решением.