Как я могу использовать значение по умолчанию на стороне БД при сохранении спящего режима?

У меня есть столбец в БД со значением по умолчанию как sysdate. Я ищу способ вставить это значение по умолчанию, пока я ничего не передаю соответствующему свойству на стороне приложения. Кстати, я использую конфигурацию на основе аннотаций.

Любой совет?


person BruceCui    schedule 05.02.2013    source источник


Ответы (3)


Причина, по которой столбец даты получает значение null при вставке, даже если он определен как default SYSDATE dbms-side, заключается в том, что значение default для столбца используется только в том случае, если столбцу не присвоено значение в запросе. Это означает, что он не должен появляться в предложении INSERT INTO, даже если он был дан null.

Если вы хотите использовать default SYSDATE на стороне СУБД, вам следует настроить @Column с помощью _ 8_, чтобы получить столбец из INSERTs SQL.

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "myDate", insertable=false)
private Date myDate;

Учтите, что этот подход всегда будет игнорировать значение, которое вы предоставляете свойству в своем приложении при создании объекта. Если вы действительно хотите иногда указывать дату, возможно, вам следует рассмотреть возможность использования триггера БД для установки значения вместо значения по умолчанию.

Есть альтернатива использованию default SYSDATE определения СУБД. Вы можете использовать @PrePersist и _ 13_ аннотации для назначения текущей даты свойству перед сохранением / обновлением. , если и только если он еще не назначен:

@PrePersist
protected void onCreate() {
    if (myDate == null) { myDate = new Date(); }
}

Этот тесно связанный вопрос предлагает разные подходы: Отметка времени создания и отметка времени последнего обновления с Hibernate и MySQL.

person Xavi López    schedule 05.02.2013
comment
Спасибо за очень подробное объяснение, Хави. Это больше, чем я ожидал, и это действительно работает! - person BruceCui; 05.02.2013
comment
@ user1900240 Рад, что помог :) - person Xavi López; 05.02.2013
comment
insertable = false у меня не сработало. Я использую Postgres, и у меня есть значение по умолчанию для столбца, но оно равно нулю. - person James Watkins; 31.01.2016
comment
Проверьте stackoverflow.com/questions/14703697/ для упрощенного ответа - person rajadilipkolli; 19.04.2017
comment
@rajadilipkolli Имейте в виду, что @UpdateTimestamp и @CreationTimestamp относятся к Hibernate и не будут доступны другим провайдерам JPA. Кроме того, он уже описан в другом ответе в связанном вопросе. - person Xavi López; 19.04.2017
comment
В моем случае у меня есть столбец modified_at, а значение по умолчанию - текущая дата и время. Единственное, что у меня сработало, это @UpdateTimestamp. Мне не нужно было звонить .flush(). Ни @Generated, ни аннотации @ GeneratedValue работали, даже после использования .flush() поле будет по-прежнему возвращается как null после .save(). - person Doug; 04.10.2017
comment
@Doug приятно знать, что вы разобрались с этим, не понимаю, как @Generated может помочь здесь, кроме предотвращения возврата к БД для получения значение после того, как оно было присвоено стороне БД. Вы пробовали insertable=false в определении @Column? @UpdateTimestamp также является очень правильным подходом, как упоминалось в комментариях выше, если вы продолжаете использовать Hibernate. - person Xavi López; 04.10.2017
comment
Да, я тоже пробовал insertable=false, но ничего не вышло. Столбец modified_at по-прежнему возвращался как null после .save(), не знаю почему ... - person Doug; 04.10.2017
comment
@Doug Ну, если бы это был UPDATE вместо INSERT, тогда updatable=false мог бы помочь. В любом случае @UpdateTimestamp уже является изящным решением, я предпочитаю использовать по умолчанию свой собственный код, а не на стороне СУБД, если это возможно. - person Xavi López; 04.10.2017
comment
Как вы думаете, почему лучше использовать значение по умолчанию в коде, а не в СУБД? - person Doug; 05.10.2017
comment
@Doug Множество причин - учитывая, что значения по умолчанию в большинстве случаев подчиняются логике приложения (т.е. вы можете по умолчанию использовать creation_date dbms-side, но не creation_user), я бы предпочел, чтобы они были вместе в одном месте (если возможно, конечно), особенно в одном где я знаю, что у меня есть контроль, и я не буду вызывать никаких побочных эффектов вместо того, чтобы разбрасываться по разным слоям. - person Xavi López; 05.10.2017
comment
@ XaviLópez Я использую @CreatedDate private LocalDateTime created; и выдает ошибку ERROR: column "date" is of type timestamp without time zone but expression is of type bytea - person ankit; 19.07.2018

Если вы используете Hibernate, вы можете просто использовать @CreationTimestamp для вставки даты по умолчанию.

@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "create_date")
private Date createDate;

и @UpdateTimestamp для обновления значения при необходимости

@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "modify_date")
private Date modifyDate;
person rajadilipkolli    schedule 19.04.2017
comment
Это помогло мне - давно искал этот ответ! Спасибо, @rajadilipkolli :) - person Custard; 12.05.2017
comment
Это то, что сработало для меня, первый ответ не сработал. Спасибо @rajadilipkolli - person Doug; 04.10.2017
comment
Это работает, но использует системное время. Каким образом можно использовать время db? Как HQL CURRENT_TIMESTAMP ()? Изменить: без изменения схемы БД? - person gagarwa; 25.06.2020

Или вы можете напрямую инициализировать свойство POJO, например:

//java code property declaration

private String surname = "default";
person Sparticles    schedule 26.06.2013