Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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
Hibernate/JPA原语映射导致奇怪的左外连接_Hibernate_Jpa - Fatal编程技术网

Hibernate/JPA原语映射导致奇怪的左外连接

Hibernate/JPA原语映射导致奇怪的左外连接,hibernate,jpa,Hibernate,Jpa,我很难实现包含基本体映射(Map)的实体的适当映射。结果SQL不是我所期望的(左外部联接),结果是在检索所述实体的列表时,应该是唯一的实体在结果中重复 以下是实体(缩写): 一些示例内容: 用户表: |username | +---------+ |admin | |brett | +---------+ 元数据表: |username |meta_key |meta_value | +---------+----------+------------+ |brett |

我很难实现包含基本体映射(Map)的实体的适当映射。结果SQL不是我所期望的(左外部联接),结果是在检索所述实体的列表时,应该是唯一的实体在结果中重复

以下是实体(缩写):

一些示例内容:

用户表:

|username |
+---------+
|admin    |
|brett    |
+---------+
元数据表:

|username |meta_key  |meta_value  |
+---------+----------+------------+
|brett    |key1      |value1      |
|brett    |key2      |value2      |
+---------+----------+------------+
通过上述映射,当我使用Hibernate检索ZPrincipal列表时,如下所示:

Criteria criteria = session.createCriteria(ZPrincipal.class);
List<ZPrincipal> list = criteria.list();
导致返回行:

|username9_1_  |username9_3_  |meta2_3_  |meta3_3_  |
+--------------+--------------+----------+----------+
|admin         |null          |null      |null      |
|brett         |brett         |key1      |value1    |
|brett         |brett         |key2      |value2    |
+--------------+--------------+----------+----------+
这将产生一个包含3个实体(即“问题”)的用户列表,“管理员”用户 对象和两个“brett”用户对象(相同)。两个“brett”实例确实都包含一个正确填充的映射。对于那些想知道的人,ZPrincipal类确实重写了equals(),它提供了基于用户名(与主键相同)的比较,并且 重写hashCode()并对用户名进行哈希

我们的商店从“模式优先”设计开始工作,模式在数据库意义上似乎是“正确的”。这个问题可能可以通过一个中间的映射表和user_元数据表中生成的id来解决,但是从阅读可用的JPA和Hibernate文档()来看,似乎可以只使用两个表来映射一组基本元素


映射中缺少什么?还是冬眠中的虫子?如果是这样的话,有人能想到一个映射工作吗?我在注释方面做了不少工作,但我没有任何乐趣。

这是预期的行为,并有记录在案。实例是完全相同的对象(因为hibernate保证具有相同主键的相同实体在JVM中只有一个实例)。您可以在客户端执行不同的操作来删除它们。您可以阅读Hibernate常见问题解答,了解他们决定不自动执行此操作的原因

使用“FROM ZPrincipal”尝试的是告诉Hibernate不要急于获取集合,因此它必须动态加载每个实体的映射(如果您打算读取每个获取的ZPrincipal的映射条目,这可能会导致N+1选择问题)。(或者Hibernate正在发出后续查询以填充映射)

最好的方法是自己执行重复数据消除并保存一些查询

参考:

似乎已解决。我将在这里为遇到此问题的任何其他人发布答案。当我将基于条件的查询替换为:
query query=session.createQuery(“FROM ZPrincipal”);
SQL查询本身是相同的,但结果是一个正确唯一的ZPrincipal列表。嗯,这是一个Hibernate错误,作为一个例子“FROM ZPrincipal”在语义上应该等同于:
Criteria=session.createCriteria(ZPrincipal.class);List-List=Criteria.List();
非常好的答案,正是我想要的。
Criteria criteria = session.createCriteria(ZPrincipal.class);
List<ZPrincipal> list = criteria.list();
select this_.username as username9_1_, 
       metadata2_.username as username9_3_, 
       metadata2_.meta_value as meta2_3_, 
       metadata2_.meta_key as meta3_3_
from users this_ 
left outer join user_metadata metadata2_ on this_.username=metadata2_.username
|username9_1_  |username9_3_  |meta2_3_  |meta3_3_  |
+--------------+--------------+----------+----------+
|admin         |null          |null      |null      |
|brett         |brett         |key1      |value1    |
|brett         |brett         |key2      |value2    |
+--------------+--------------+----------+----------+