2014-05-21 2 views
0

У меня есть следующий пункт и видео классы:Morphia @PrePersist в @Embedded объекты

import org.mongodb.morphia.annotations.Entity;  
@Entity(value = "item") 
public class Item{ 
    @Id 
    ObjectId id; 
    Date modified; 
    String title; 
    Video video; 
    @PrePersist 
    void preItem() { 
     modified = new Date(); 
    } 
} 
import org.mongodb.morphia.annotations.Embedded;  
@Embedded 
public class Video{ 
    Date modified; 
    @PrePersist 
    void preVideo() { 
     modified = new Date(); 
    } 
} 

В любое время я сохранить объект элемента, дата изменяется в пункте и в видео классов. Это ожидаемый результат при звонке: datastore.save(this).

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

Сравнивая новый объект (в памяти) со старым (в базе данных) может быть решение:

//Inside the Item class 
@PrePersist 
void preItem(){ 
    Item oldItem=find.query().field("_id").equal(this.id) 
     .field("video").equal(this.video).get() 
    if(oldItem != null) oldItem.video.modified;   
} 

Но это означает, что в каждом вызове datastore.save(this) я опрашивает дб. Не рекомендуется ли с точки зрения производительности? Есть ли другие способы сделать это?

EDIT: Целью является изменение реальной даты. Представим себе, что я изменяю заголовок элемента: item.title="Whatever". Затем я выполняю item.save(). Это обновит мою дату в item.modified и в item.video.modified. Но это на самом деле неправильно: элемент был изменен, но не видео.

ответ

0

Обновленный ответ:

Это не сработает. prePersist() всегда будет работать по полному документу, когда вы позвоните save. Вам нужно будет выдать запрос на обновление или установить его явно.

AFAIK MongoDB не проверяет изменения, так что это не будет работать без какого-либо ручного вмешательства


Старый ответ:

Смешивание хранилищу на сущности, выглядит странно для меня - я бы старайтесь избегать этого. И вы правы, производительность пострадает, и вы можете (как правило) столкнуться с проблемами параллелизма, поскольку транзакций нет.

Не работает ли следующая работа?

@PrePersist 
void preItem() { 
    modified = new Date(); 
    video.setModified(new Date()); // or probably fetch new Date() once and use it for both 
} 

PS: Так как у вас уже есть дата в документе, зачем вам это нужно, чтобы сохранить его в встроенный поддокументе, а? Они должны всегда совпадать, не так ли?

+0

Нет. Возможно, я не понял свой вопрос: я хочу, чтобы в видеоролике была только новая дата, когда видеообъект действительно был изменен. Чтобы сохранить объект Item, не означает, что объект видеоизображения внутри объекта был изменен. Возможно, объект item имеет больше полей, и я их изменяю, но я ничего не изменяю внутри видеообъекта. –

+0

Обновлено мой ответ – xeraa

+0

Спасибо. Это то, что я думал. Я думаю, лучшая идея с точки зрения производительности - обновить измененное поле в каждом объекте, каждый раз, когда я знаю, я действительно модифицировал этот объект. Спасибо за ваше мнение в любом случае –

Смежные вопросы