2009-11-17 17 views
11

Я немного поиграю с JPA (особенно для Eclipselink). У нижеприведенного объекта есть отметка времени , которая должна отображаться всякий раз, когда этот объект был последним обновлен.Последняя метка времени с JPA

Каковы стратегии для автоматического обновления JPA этой метки времени каждый раз, когда этот объект изменен?

Как бы я мог пойти, если бы мне также нужна метка времени создания, установленная только тогда, когда объект сначала сохраняется, и никогда не разрешается менять его снова?

@Entity 
public class Item implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private Integer id; 
    private String note; 


    public Item() { 
    } 


    @Id 
    @GeneratedValue(strategy=SEQUENCE) 
    @Column(unique=true, nullable=false) 
    public Integer getId() { 
     return this.id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 


    @Column(length=255) 
    @Column(nullable=false) 
    public String getNote() { 
     return this.note; 
    } 

    public void setNote(String note) { 
     this.note = note; 
    } 

    @Column(nullable=false) 
    public Timestamp getUpdated() { 
     return this.updated; 
    } 

    public void setUpdated(Timestamp updated) { 
     this.updated = updated; 
    } 


} 

ответ

16

Использование @PrePersist и @PreUpdate аннотациями и написать свой собственный слушатель событий.

Подробнее см. this answer. Он помечен как Hibernate, но применим к любому провайдеру JPA.

1

если вы используете MySQL, я думаю, что вы можете сделать следующее, чтобы отключить временные метки от обновления от лица

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

для оракула вы времени должно установить временные метки от объекта, используя @PreUpdate аннотации как объяснено выше.

+0

Это неверно по многим причинам: (1) вышеуказанное предполагает, что вы вручную обновляете метку времени, поэтому установка «обновляемая» бессмысленна; (2), следовательно, вышеупомянутое не будет работать без прослушивателей событий @PreUpdate/@PrePersist; (3) если вы хотите, чтобы база данных генерировала ваши отметки времени (что, как вам кажется, подразумевается), вы должны пометить свои свойства как сгенерированные, которые ** не ** в стандарте JPA; (4), наконец, MySQL не позволит вам иметь две автоматические обновленные временные метки в одной таблице. – ChssPly76

+0

Что касается mysql, вы можете создать один или несколько триггеров для обновления любого количества столбцов, таких как временная метка - вы не ограничены 1 автоматической обновленной меткой времени в таблице. – nos

+0

в MySql вы также можете создать таблицу с двумя временными метками и вставить NULL в оба поля при вставке записи. создать таблицу ts ( last_updated_ts TIMESTAMP, created_ts TIMESTAMP, имя varchar (5)); Вставить в ts (last_updated_ts, created_ts, name) значение (null, null, 'test'); Определенный триггер или аннотация лучше в зависимости от того, как клиент обращается к базе данных. – surajz

1

Действительно, surajz ответ работает. Рассмотрим сценарий, в котором вы отслеживаете 2 временных метки. Вы хотите вручную обновить их через объект. Вам нужно будет установить один на updateble=false (тот, который вы не хотите обновлять при обновлении записи), и оставляйте другого бесплатным для обновлений.

Это то, что сработало для меня.