2017-02-22 49 views
0

У меня есть один объект JPA, который имеет созданную дату и измененную колонку даты. При создании/сохранении созданная дата и измененная дата генерируются значением по умолчанию, заданным в базе данных, которое является меткой времени. Однако при создании, когда я пытаюсь выполнить обновление/слияние, я не могу понять, как изменить измененную дату, используя значение по умолчанию в базе данных. Любой совет? Это текущая настройка:JPA EntityManager - использование слияния для создания значения по умолчанию?

.... 
@Temporal(TemporalType.DATE) 
@Column(name="CREATED_DATE", insertable = false, updatable = false) 
private Date createdDate; 

@Temporal(TemporalType.DATE) 
@Column(name="MODIFIED_DATE", insertable = false) 
private Date modifiedDate; 
.... 

-

public Database changeDate(Database oldValues) 
    Database newvalues = new Database(); 
    .... 
    newValues.setCreatedDate(oldValues.getCreatedDate); 
    //newValues.setModifiedDate(); <-- (Should use the default value in the database) 
    .... 
    em.merge(newValues); <-- (EntityManager) 
    em.getTransaction().commit(); 

** Только в случае, если я не сделал себе ясно, я просто не знаю, как сделать это обновление с набором значения по умолчанию в базе данных.

+0

Чтобы сделать это немного понятнее, вы говорите: «Я пытаюсь обновить newValues.modifiedDate до нового значения Date(), но после транзакционного фиксации в БД нет обновления» или «Я пытаюсь обновить newValues .modifiedDate для нулевого значения, но я получаю исключение "? –

+0

Я хотел попытаться обновить его до значения по умолчанию, которое оно хранило в базе данных. Установка его в значение null не помогла. Я могу выполнить новый маршрут Date(), но я бы предпочел значение по умолчанию. –

+0

Я бы предложил изменить ваш вопрос и удалить «null». Если вы переформулируете свой вопрос, чтобы объяснить, что именно вы пытаетесь сделать, нам будет намного легче помочь. –

ответ

0

Существует аннотацию можно использовать javax.persistence.Version

@Column(name="CREATED_DATE", updatable = false) 
private java.sql.Timestamp createdDate = new java.sql.Timestamp(System.currentTimeMillis()); 

@Version 
@Column(name="MODIFIED_DATE") 
private java.sql.Timestamp modifiedDate; 

Оба поля нужен только геттер, нет сеттера. JPA будет сравнивать и обновлять значение timestamp на своем собственном. В противном случае, если вы полагаетесь на базу данных, чтобы сгенерировать ее для вас, вы также можете попробовать @GeneratedValue(strategy = GenerationType.IDENTITY) или AUTO, но я уверен, что это не сработает в спящем режиме. Возможно, он будет работать и в других провайдерах JPA. В Hibernate значение AUTO всегда возвращается к SEQUENCE, поэтому нет шансов на то, что эта стратегия будет работать.

+0

Это было очень близко - единственная проблема заключалась в том, что аннотация GeneratedValue уже используется для ID, и, по-видимому, вы можете иметь по одному на сущность (возможно, я должен был сказать, что это начало, но я думал, что это не будет большой проблемой). И тип Date не разрешен для версии. Я попытался использовать Timestamp только для того, чтобы убедиться, что это сработает, но тогда сущность не может быть сопоставлена ​​с базой данных. –

+0

Если вы усекаете микросекунды (что-то меньшее, чем миллисекунды, действительно) из значений в базе данных, '@ Version' с Timestamp должен работать. Это то, что нам нужно было сделать, прежде чем мы перешли на Java 8 и переключились на «Instant». – coladict

+0

Это, похоже, сработало! Большое спасибо! –

1

Вы хотите установить значение Null на сегодняшний день. добавьте свойство nullable в аннотацию даты. это будет работать.

добавить его в аннотации обнуляемой = истинного

@Temporal(TemporalType.DATE) 
@Column(name="CREATED_DATE",nullable = true, insertable = false, updatable = false) 
private Date createdDate; 

@Temporal(TemporalType.DATE) 
@Column(name="MODIFIED_DATE", nullable = true, insertable = false) 
private Date modifiedDate; 
+0

В базе данных я установил, что измененная дата не может быть нулевым значением. С аннотацией это просто дает мне ту же ошибку. - что значение не может быть установлено равным null. Я не думаю, что я сделал это ясно в своем вопросе. Извините, что: c –

+0

изменить на null в базе. что будет работать –

0

Если я правильно понял вопрос правильно, вы хотите, чтобы убедиться, что столбец MODIFIED_DATE всегда получает значение в CURRENT_TIMESTAMP. Затем, когда объект базы данных обновляется, а другие поля изменяются, столбец MODIFIED_DATE будет установлен в CURRENT_TIMESTAMP.

Я предполагаю, что ваша таблица DB выглядит примерно так:

CREATE TABLE Database (
    ID int NOT NULL, 
    CREATED_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
    MODIFIED_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP 
) 

То, что вы хотите сделать, это добавить метод @PreUpdate к классу сущностей базы данных и он установлен атрибут ModifiedDate к новой дате () каждый раз. Затем, всякий раз, когда делается обновление для объекта, столбец MODIFIED_DATE будет установлен на новую дату!

Вот пример:

@PreUpdate 
protected void onUpdate() { 
    modifiedDate = new Date(); 
} 

Попробуйте простой пример и посмотреть, как это работает:

em.getTransaction().begin(); 
Database db = new Database(1, "First Value"); 
em.persist(db); 
em.getTransaction().commit(); 

em.getTransaction().begin(); 
Database db2 = em.find(Database.class, 1); 
db2.setValue("New Value!"); 
em.getTransaction().commit(); 
+0

, так что в основном с использованием нового маршрута Date() - пока это мой единственный вариант. PreUpdate - довольно приятная функция, она не знала, что она существует. –

+0

@ RaccoTaco Проблема заключается в том, что использование функциональных возможностей по умолчанию для вашей таблицы БД предназначено только для вставки НОВЫХ строк. Если вы вставляете новую строку и не получаете значение для столбца со значением по умолчанию, значение по умолчанию используется для того, чтобы значение было не равным NULL. В вашей usecase после того, как значение инициализируется по умолчанию, его нельзя отменить, не удаляя строку и не вставляя ее. –

+0

Хотя это может сработать, я предупреждаю об этом. В целом, я считаю, что это плохое дизайнерское решение для размещения этой бизнес-логики в БД. Кроме того, мой ответ предлагает большую гибкость для управления вашей стоимостью. Опора на провайдера или БД для установки значения означает, что изменение значения вручную либо невозможно, либо сложно –