每个实体休眠两个表

时间:2013-05-26 00:54:18

标签: java spring hibernate sqlite hibernate-annotations

我有一个实体 - 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_tableuser2中的users_2_table

由于系统限制,我无法将这两个对象放在一个表中。 (即使创建额外的字段也是个坏主意)。

我可以在没有子类化的情况下这样做吗?使用programmaticaly hibernate配置?

5 个答案:

答案 0 :(得分:33)

<强>前言

即使在SO上,这也是一个广泛提问的问题,而且答案也广泛地与Subclass或实际SuperClass方法相关(例如[1])

实际答案:

在这些帖子[2],[3]上,他们建议使用带有EntityName参数的xml映射。

因此,使用xml进行映射不需要supeclass,只需将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&amp;使用3作为此片段的基础。官方来源[4]

匹配后:

关于第一个问题的一个答案实际上链接到这篇文章[5],有不同的方法:

你说再见对象的第一个实例,将数据克隆到新实例并用不同的名称保存。因此,不会违反Hibernate逻辑和每个人的内容:两个表中的数据相同而且没有使用子类。

那么,该方法的实现或代码或可信度是如此,我还没有测试过。

另一个案例:

在这篇文章[6]中,还有另一个人试图用更简单的方法挑战超类方法,但同样,最可信的答案表明不可能采用另一种方式,官方的非xml方法是上述子类方法。

<强>来源

[1] How to map one class to different tables using hibernate/jpa annotations

[2] Map Two Identical tables ( same schema...) to same entity in Hibernate

[3] How to map 2 identical tables (same properties) to 1 entity

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

[5] Hibernate 4: One class mapping Two tables - How to persist one object on both tables?

[6] Hibernate Annotation for Entity existing in more than 1 catalog

答案 1 :(得分:3)

它也可以使用默认实体和另一种实体:

<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)

替代方案。

答案 2 :(得分:1)

您可以使用配置执行此操作:

  • 为同一个实体类 name 创建两个映射,但为它们提供不同的逻辑 entity-name 名字。
  • 然后使用 Session 方法,您可以将 entityName 作为参数来区分彼此。

这实现了什么?

  • “虚拟子类型”
  • 将数据检索到类型中时,您必须指定一个 entity-type 或另一个(因此暗示一个表或另一个表)
  • 修改数据并进行保存时,必须指定相同的 entity-type - 尝试使用其他 entity-type 进行更新被hibernate拒绝了。否则,已修改的实体已经填充了标识符,因此hibernate将尝试更新而不是插入,但这会在数据库中失败 - 尝试更新表中从未存在的数据。
  • 这会导致隔离 - 在处理实体或实体列表时,您必须提交一个实体类型,并且不能将两者混合使用。即“虚拟子类型”

费用是多少?

  • 输入非常弱。编译器和运行时没有指示真正的子类型。错误等待发生,调试可能会很棘手。
  • 这是非标准的。 JPA已经避开了这一点,我相信它并没有被包含在内,并且有充分的理由。
  • 您必须使用XML,而不是注释。
  • 您必须调用异常方法,包括“entity-type”参数。

是否有超过子类型的好处?

  • 我无法看到

你应该这样做吗?

  • 我不这么认为!使用子类型和标准代码。

答案 3 :(得分:0)

虽然我从未使用过,但在休眠中有一个辅助表的概念。而@SecondaryTables是hibernate中的注释,实体可以通过该注释映射多个表来获取数据。获取数据的实体应该具有@SecondaryTables注释。它基于主键和外键并且还基于唯一约束来关联辅助表。

以下是我在google上找到的一个示例,请检查它是否有助于您实现:

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

答案 4 :(得分:0)

我知道这个问题是很久以前问过的。但我想提出一种替代方法,而不使用任何休眠方式。对于那些不想使用xml配置的人。

使用commun列的getter和setter方法声明一个接口,然后使两个实体类实现此接口。 照常在这两个实体类中保留映射注释,然后在您的代码中可以改为调用此接口的方法。