Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate映射用于这种情况,其中键也被用作多对一参数_Java_Database_Hibernate_Orm - Fatal编程技术网

Java Hibernate映射用于这种情况,其中键也被用作多对一参数

Java Hibernate映射用于这种情况,其中键也被用作多对一参数,java,database,hibernate,orm,Java,Database,Hibernate,Orm,我想知道是否有一种方法可以对以下内容进行Hibernate映射。我花了两天的时间在这上面说没有 有两个表,具有一对多关系 +---------------------+ +-----------------+ | versioned_entity | | basic_entity | +---------------------+ +-----------------+ | fk_BasicEntityId | * 1 | id

我想知道是否有一种方法可以对以下内容进行Hibernate映射。我花了两天的时间在这上面说没有

有两个表,具有一对多关系

+---------------------+       +-----------------+
|  versioned_entity   |       |  basic_entity   |
+---------------------+       +-----------------+
| fk_BasicEntityId    | *   1 | id              |
| version             |-------| active_version  |
| ...                 |       | ...             |
+---------------------+       +-----------------+
休眠映射:

<class name="my.VersionedEntity" table="versioned_entity">
  <composite-id>
    <key-many-to-one name="basicEntity" column="fk_BasicEntityId"/>
    <key-property name="version"/>
  </composite-id>
  ...
</class>

<class name="my.BasicEntity" table="basic_entity">
  <id name="id">
  <property name="activeVersion" not-null="true">
    <column name="active_version"/>
  </property>
  ...
</class>
当前实现是在Java中完成的,只需迭代给定基本实体的所有版本化实体,并检查其版本是否与活动版本匹配。不用说,这不会扩展并导致性能问题

所以我继续将其转移到数据库级别。看起来容易吗?所以我想!我接着在基本实体的Hibernate映射中添加了以下内容:

<many-to-one name="activeVersionedEntity" not-null="false" insert="false" update="false">
  <column name="id" unique="true" not-null="true"/>
  <column name="activeVersion"/>
</many-to-one>

对于具有组合键的
版本化的\u实体
,此处需要双栏。 不幸的是,这不起作用-当调用
be.getActiveVersionIdentity()
时(在同事的机器上,它在Hibernate内部抛出StackOverflowerError),JVM将在没有跟踪的情况下死亡。我怀疑发生这种情况是因为“id”也是一个标识符,因为我对同一个类有非常相似的映射,其中column不是一个标识符,并且这是正确的

我可能可以用HQL来实现这一点,但这需要我将此方法移动到DAO类中,这尤其令人尴尬,因为需要更改API(不是一个选项)。在my.BasicEntity::GetActiveVersionIdentity()内部使用DAO调用是另一个大禁忌:我不能混淆不同的抽象层。解决这一问题的另一种方法是研究拦截器/事件,但是这也可能是超出框架目的的选项之一(我不应该关心像这样的低级事情,是吗?)

我正在运行Hibernate版本:3.2.7GA/Spring2.5.6。文档非常糟糕——我看了三本不同的Hibernate书籍、在线文档、论坛等


非常感谢您的帮助。

为什么要将活动\u版本映射为属性?我怀疑这是一个整数,对吗?为什么不将活动_版本更改为VersionIdentity类型?这样,它将是一种简单的一对一关系

+---------------------+       +-----------------+
|  versioned_entity   |       |  basic_entity   |
+---------------------+       +-----------------+
| fk_BasicEntityId    | *   1 | id              |
| version             |-------| active_version  |
| ...                 |       | ...             |
+---------------------+       +-----------------+
更新:

我们正在为我们的一个站点使用此映射:

<many-to-one class="my.VersionedEntity" name="currentVersion" lazy="false" /> 


听起来你好像在试图双重映射某个列。我还没有详细了解您的问题,但是您是否考虑过在其中一个映射上使用update=false和insert=false?这应该使您能够将同一列作为关系和整数进行双重映射。更多信息。

您是在建模双向引用关系还是继承层次结构

如果对象模型是继承层次结构,那么关系不需要是双向的,解决方案是从子类DAO获取子类实例。这样就不需要在基类DAO中从基类导航到子类。这就是我试图在我的原始答案(以下)中解释的内容

如果对象模型是双向关系,则需要在关系的“一”端的集合或包上设置inverse=“true”-在本例中为BasicEntity

Hibernate 3允许在关系的“一”端使用索引集合,但是Hibernate 2的set或bag功能应该足以测试该理论

此链接可能有助于: 另外:快速休眠pp142-145;冬眠行动pp108-111


如果我正确理解了这个问题,那么您希望使用以下获得的数据从两个表构建VersionIdentity:

my.BasicEntity basic = my.BasicEntityDAO.get();
my.VersionedEntity activeVersion = basic.getActiveVersionedEntity();
select * from basic_entity be, versioned_entity ve where ve.id = be.id and ve.id = <id> and ve.active_version=<version>
您是否可以实现这样的方法:

public my.VersionedEntity my.VersionedEntityDAO.getActive();

问题是,当Hibernate加载BasicEntity并遇到属性ActiveVersionIdentity时,它会尝试再次加载BasicEntity以表示密钥。导致堆栈溢出错误,因为BasicEntity还需要加载活动版本。不管天气好坏,多对一都是懒惰的,因为懒惰意味着它只填充两列值,并留下VersionIdentity对象供以后加载。是的,此映射会导致堆栈溢出,因为它会导致循环依赖关系。您必须从版本化的_实体端断开映射的方向性。因此,在版本化的_实体中将不会有任何多对一映射将其与基本度关联。另一方面,如果您遇到性能问题,我将不鼓励使用复合ID!解决这个问题的更好方法是将id列添加到版本化的\u实体中,并使用它而不是活动的\u版本。除非您需要使用:entity active_version的查询,否则需要将-version作为整数,将版本化对象作为对象。我相信拥有前者并不能阻止我拥有后者,是吗?如果你可以简单地使用getActiveVersion().getVersion()来获得版本,为什么两者都有呢?否则,您将面临两个属性不同步的风险(结果可能是相当奇怪的行为)。我们对我们的一个站点使用了完全相同的方法,效果非常好。您在这里描述的是org.hibernate.MappingException:外键(FK4F44784EF87DDA8D:basic_entities[active_version])必须与引用的主键(versioned_entity[fk_BasicEntityId,version])具有相同的列数使用上述数据模型。非常感谢您的帮助。我已经尝试了您建议的方法,但仍然遇到JVM崩溃。我假设这可能是由于复合id被用作多对一列参数造成的(请参见上面的注释)。你是不是碰巧在你的环境中使用了类似的组合?@Sindri我没说这对描述的情况有用。我刚刚粘贴了我们正在使用的内容。只是仔细检查,发现我们既没有使用复合id,也没有增加版本号。我们只是在需要的地方按日期排序,并使用“常规”自动递增id。您真的需要每个基本单位的连续版本编号吗?如果是,