Проблема с обновлением bean-компонента Gwt Requestfactory

У меня есть довольно интересная проблема. Я устанавливаю некоторые значения на сервере, отправляю bean-компонент клиенту, а затем он возвращается на сервер без этих значений.

Вот что я делаю:
1. Клиент запрашивает несколько bean-компонентов из БД через EntityRequest.getEntity(params)
2. Я извлекаю bean-компонент из базы данных через Hibernate
3. Я устанавливаю некоторое временное свойство (мне нужно их на стороне клиента и не хочет, чтобы они сохранялись в БД)
4. Отправьте bean-компонент через метод EntityRequest клиенту.
5. Клиент изменяет некоторые другие значения и вызывает сохранение.
6. Сервер получает вернуть свой bean-компонент и
- он правильно установил свойства от клиента
- свойства, установленные на сервере (шаг № 3), УДАЛЕНЫ / ИГНОРИРУЮТСЯ.

Похоже, что механизм RF отправил бы мне только что загруженную версию БД только с изменениями от клиента. Я провел некоторое исследование, и похоже, что должна быть какая-то проблема с версией bean-компонента. Компонент имеет набор версий (см. ниже), и он используется Hibernate и, я думаю, RF.

Что я должен сделать, чтобы получить свою ценность для клиента и обратно? Я пробовал некоторые "entity.version++;" на шаге 3, но это не работает.

@Entity
public class Person {

    @Id
    @GeneratedValue
    private Long id;

    @Version
    private Integer version;

    @Field
    private String name;

    @Transient
    private Long participationId;

    ...

    public Long getId() {
        return id;
    }

    public Integer getVersion() {
        return version;
    }

    ...
}

public static Person findPerson(Long id) {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    try {

        Object p = session.get(Person.class, id);
        session.getTransaction().commit();

        return p != null ? (Person) p : null;

    } catch (RuntimeException e){
        logger.error("Person.findPerson", e);
        session.getTransaction().rollback();
        throw e;
    }
}

person hostnik    schedule 08.11.2012    source источник
comment
Не могли бы вы поделиться своим кодом Locator? (или метод public static Person findPerson(Long id) в классе Person, в зависимости от того, что вы используете)   -  person Thomas Broyer    schedule 08.11.2012
comment
Томас, я добавил код findPerson выше к вопросу. Я также провел некоторое исследование и обнаружил, что на самом деле findPerson(id) вызывается при реконструкции объекта домена. Почему он не использует внутренний кеш? Могу ли я кодировать findPerson по-другому, чтобы использовать кеш объектов домена? Спасибо.   -  person hostnik    schedule 09.11.2012
comment
Вы ДОЛЖНЫ (как в: ДОЛЖНЫ, если вы действительно не знаете, что делаете) использовать шаблон open session in view с JPA/Hibernate/чем угодно, поэтому делитесь одним и тем же сеанс (и его внутренний кеш) на протяжении всего запроса (по другим причинам, кроме производительности). Однако между запросами, возможно, используйте другой общий кеш, но лучше подождать, пока он вам действительно не понадобится (преждевременная оптимизация — корень всех зол)   -  person Thomas Broyer    schedule 09.11.2012
comment
Кстати, вам не нужна транзакция для операции только для чтения, и вам также не нужна проверка на ноль (приведение null к Person все равно будет работать)   -  person Thomas Broyer    schedule 09.11.2012
comment
Томас, спасибо за ответы! Это помогло мне лучше понять механизм RF и найти решение. Уродливый хак: еще одно временное значение, участиеStoreId. Всякий раз, когда я хочу сохраниться, я копирую его в клиенте из идентификатора участия в участиеStoreId, и оно передается на сервер. Не могли бы вы ответить, что я могу отдать вам должное, и я закрываю вопрос?   -  person hostnik    schedule 12.11.2012
comment
AFAICT, на ваш вопрос до сих пор нет ответа. Возможно, вы нашли обходной путь, но это, ну, обходной путь (я даже не понимаю, что вы сделали и как это решило вашу проблему, поскольку я на самом деле не знаю, что было не так с самого начала).   -  person Thomas Broyer    schedule 12.11.2012
comment
Спасибо за подсказку OSIV. Это помогло мне легко/решить некоторые другие проблемы. Отсутствуют некоторые конкретные рекомендации GWT+Hibernate+RF. Везде есть обрывки и миры, но трудно понять целое.   -  person hostnik    schedule 15.11.2012


Ответы (1)


С помощью Томаса Бройера я лучше понял механизм RequestFactory, и это привело меня к решению. RequestFactory при возврате объекта со стороны клиента не извлекает объект домена из кеша, а извлекает новый и выполняет сравнение с ним. Выборка выполняется либо с помощью локатора, либо с помощью функции find(id) объекта домена. В моем случае это было find(id).

Я знаю, что это уродливый хак, но он работает. Это на моем объекте

public class Person {
...
@Transient
private Long participationId;

@Transient
private Long participationStoreId;
...
}

Прежде чем отправить его в РФ, я загружаю идентификатор участия. На стороне клиента, чтобы сохранить его, перед отправкой обратно я делаю:

person.setParticipationStoreId(person.getParticipationId());

Прежде чем ты забросаешь меня яйцами, повторю: я знаю, что это отвратительная поделка. Но в некоторых случаях мне нужно какое-то значение объекта для клиента и обратно, и я не хочу его в БД. Это был единственный работающий способ.

person hostnik    schedule 14.11.2012