Подтвердить что ты не робот

Спящий режим на две группы на одну сущность

У меня есть одна сущность - User. Он описывается User.class.

Hibernate создает одну таблицу для каждого объекта, поэтому, когда я вызываю session.save(user), мои данные всегда сохраняются в этой таблице.

Теперь мне нужна другая таблица для данных того же типа User, и мне нужно сохранить мой объект только в этой таблице.

Структура данных (что-то вроде этого):

table users_1_table{
  string id;
  string username;
}

table users_2_table{
  string id;
  string username;
}

работать с этим:

session.save(user1,"users_1_table")
session.save(user2,"users_2_table")

и в результате я должен иметь user1 в users_1_table и user2 в users_2_table.

Из-за системного ограничения я не могу поместить эти два объекта в одну таблицу. (Даже создание дополнительного поля - плохая идея).

Могу ли я сделать это без подкласса? Использование программной конфигурации спящего режима?

4b9b3361

Ответ 1

Предисловие:

Это часто задаваемый вопрос даже в отношении SO, а также ответы на многие вопросы связаны с Subclass или фактически SuperClass подходом (например, [1])

Фактический ответ:

В этих сообщениях [2], [3] они предлагают использовать сопоставление xml с параметром EntityName.

Итак, для сопоставления с xml вам не нужен суперкласс, просто задайте параметр EntityName двум одинаковым сопоставлениям.

Пример сопоставления:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="DomainModel.User, DomainModel"
     table="User1Object" entity-name="User1Object">  
         <id name="_id" access="field" column="id">
             <generator class="assigned"/>
         </id>
        <property name= ...>
 </class>
 <class name="DomainModel.User, DomainModel"
     table="User2Object" entity-name="User2Object">
         <id name="_id" access="field" column="id">
            <generator class="assigned"/>
         </id>
        <property name= ...>
</class>
</hibernate-mapping>

Затем, в зависимости от того, какой тип сущности вам нужен, вы вызываете соответствующие методы сеанса как:

_session.Save("User1Object", user1)

или

_session.Save("User2Object", user2)

Сообщения 2 и 3 были использованы в качестве основы для этого фрагмента. Официальный источник [4]

После матча:

В одном ответе на первый вопрос, который фактически является ссылкой на этот пост [5], существует другой подход:

Вы говорите "пока" первому экземпляру объекта, клонируете данные в новый экземпляр и сохраняете это с другим именем. Таким образом, нет нарушений в логике Hibernate и всем содержимом: одни и те же данные в двух таблицах и никакие подклассы не используются.

Что ж, реализация, или код, или доверие к этому подходу такие-то, я их не проверял.

Другой случай:

В этом посте [6] есть еще один человек, пытающийся оспаривать подход суперкласса с помощью чего-то более простого, но, опять же, самый надежный ответ гласит, что это невозможно с другой стороны, официальный Подход xml - это упомянутый подход подкласса.

Источники

[1] Как сопоставить один класс разным таблицам с помощью аннотаций hibernate/jpa

[2] Сопоставить две одинаковые таблицы (одну и ту же схему...) с одним и тем же объектом в Hibernate

[3] Как сопоставить 2 одинаковые таблицы (одинаковые свойства) с 1 объектом

[4] http://docs.jboss.org/hibernate/core/3.2/reference/en/html/mapping.html#mapping-entityname

[5] Hibernate 4: отображение одного класса. Две таблицы. Как сохранить один объект в обеих таблицах?

[6] Hibernate Аннотация для сущности существует более чем в 1 каталоге

Ответ 2

Также он работает с использованием объекта по умолчанию и альтернативного:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="DomainModel.User, DomainModel"
     table="User1Object">  
         <id name="_id" access="field" column="id">
             <generator class="assigned"/>
         </id>
        <property name= ...>
 </class>
 <class name="DomainModel.User, DomainModel"
     table="User2Object" entity-name="User2Object">
         <id name="_id" access="field" column="id">
            <generator class="assigned"/>
         </id>
        <property name= ...>
</class>
</hibernate-mapping>

Для стандартного метода вы можете использовать метод

_session.Save(user1)

и

_session.Save("User2Object", user2)

для альтернативного.

Ответ 3

Вы можете сделать это с помощью конфигурации:

  • Создайте два сопоставления для одного и того же класса сущностей name, но укажите им разные логические entity-name и таблицу.
  • Затем используйте методы Session, где вы указываете entityName как параметр, чтобы отличать один от другого.

Что это достигается?

  • "Виртуальный подтипирование"
  • При извлечении данных в тип необходимо указать один entity-type или другой (таким образом, подразумевая одну таблицу или другую)
  • Когда вы изменяете данные и сохраняете их, вы должны указать один и тот же entity-type - попытка смены другого entity-type должна быть отклонена спящим режимом. В противном случае модифицированные объекты уже будут заполнены идентификатором, поэтому hibernate будет пытаться обновить, а не вставлять, но это приведет к сбою в базе данных - попытка обновить данные, которые никогда не существовали в таблице.
  • Это приводит к сегрегации - вы должны зафиксировать один тип сущности при работе над сущностью или списком сущностей и не можете смешивать их. то есть "виртуальный подтипирование"

Каковы затраты?

  • Это дает очень слабую типизацию. Компилятор и среда выполнения не имеют указаний на истинный подтип. Ошибки ждут и могут быть сложными для отладки.
  • Это нестандартное. JPA справилась с этим, я считаю, что это не для радара для включения, и по уважительной причине.
  • Вы должны использовать XML, а не аннотации.
  • Вы должны вызывать необычные методы, включая параметр "тип сущности".

Есть ли преимущества над подтипированием?

  • Нет, что я вижу

Должны ли вы это сделать?

  • Я так не думаю! Используйте подтипирование и стандартный код.

Ответ 4

Хотя я никогда не пользовался, но есть концепция вторичной таблицы в спящем режиме. А @SecondaryTables - это аннотация в спящем режиме, с помощью которой сущность может отображать более одной таблицы для извлечения данных. Объект, который извлекает данные, должен иметь аннотации @SecondaryTables. Он связывает вторичную таблицу на основе первичного и внешнего ключей, а также на основе уникальных ограничений.

Вот один образец, который я нашел после выполнения google, проверьте, помогает ли это вам:

http://www.concretepage.com/hibernate/secondarytables_hibernate_annotation.php

Ответ 5

Я знаю, что этот вопрос задавали давно. Но я хотел бы предложить альтернативный способ, без использования каких-либо спящих вещей. Для тех, кто не хочет использовать конфигурацию XML.

Объявите интерфейс с методами getter и setter для столбцов commun, а затем заставьте свои классы сущностей tow реализовать этот интерфейс. Оставьте аннотации сопоставления в этом классе двух сущностей как обычно, затем в своем коде вы можете вместо этого вызывать метод этого интерфейса.