Спящий режим загрузка объекта сразу после создания

#java #hibernate #spring #orm #persistence

#java #спящий режим #весна #orm #сохранение

Вопрос:

У меня есть объект гибернации, который имеет одно или несколько <many-to-one сопоставлений, например

 <hibernate-mapping>
  <class name="MyClass" table="my_table">
    <cache usage="nonstrict-read-write"/>
      <composite-id>
        <key-property name="id" length="30"/>
        <key-property name="someRef" length="30" column="foreign_key_to_something"/>
      </composite-id>
    <many-to-one name="mappedProperty" column="foreign_key_to_something" insert="false" update="false"/>
    <property name="foo" column="foo"/>
    ...
  </class>
</hibernate-mapping>
 

Мне нужно создать такую сущность и получить немедленный доступ к mappedProperty ней после создания. Я вижу здесь два подхода:

1) Создайте объект и установите все связанные <many-to-one сопоставления вручную. Очевидным недостатком этого подхода является требуемая работа, особенно если количество отображаемых <many-to-one объектов велико. Зачем делать что-то вручную, если фреймворк может сделать это за вас?

2) Создайте объект, только инициализировав необходимые параметры (например, первичные ключи id и someRef в приведенном выше случае), затем сохраните и повторно загрузите его немедленно. Загрузка должна инициализироваться mappedProperty автоматически или обеспечивать отложенную инициализацию по требованию.

Я предпочитаю вариант 2), однако я заметил, что в некоторых случаях mappedProperty свойство не задано. load() возвращает тот же объект, который я передал create() , только с инициализированными первичными ключами. Я все еще не уверен, почему это происходит, но чтобы бороться с этим, мне пришлось бы отсоединить объект от сеанса гибернации, чтобы load() он был вынужден перейти к базе данных и получить заново. Опять же, звучит довольно сложно, не так ли?

Я что-то здесь упускаю? Существуют ли какие-либо другие способы решения этой проблемы?

Ответ №1:

Когда вам нужно обновить состояние объекта из базы данных, используйте refresh() .

Комментарии:

1. Примечание: если кто-то еще будет использовать этот подход, не забудьте сделать session.flush() это раньше refresh() . Для получения более подробной информации см.: forum.hibernate.org /…

Ответ №2:

load и get верните объект из сеанса, если он уже есть. Таким образом, ваш второй вариант потребует, чтобы вы очистили, затем удалили объект из сеанса, а затем перезагрузили его (выполнив запрос select для известных вам данных). Вызов обновления сделал бы то же самое, проще, но все равно выдал бы дополнительный запрос select ни для чего.

Я действительно предпочитаю первый вариант: просто убедитесь, что каждый раз, когда устанавливается ассоциация, также отображается соответствующее сопоставленное свойство. Вы несете ответственность за согласованность и инварианты объектов (как и в случае двунаправленных ассоциаций, где должны поддерживаться обе стороны).

Третьим вариантом было бы полностью удалить сопоставленное свойство и просто вызвать entity.getKey().getSomeRef().getId() .

Комментарии:

1. Спасибо, но, как я уже сказал, с первым вариантом действительно неудобно работать, если ваша сущность имеет несколько сопоставлений. Некоторые из моих объектов имеют около 10 зависимых объектов, и установка их всех была бы кошмаром: (