[英]Does JPA @ElementCollection annotation always produce an one-to-many relationship?
[英]Eager/Lazy loaded member always empty with JPA one-to-many relationship
我有兩個實體,一個用戶和一個角色,用戶與角色之間存在一對多的關系。 表格如下所示:
mysql> select * from User;
+----+-------+----------+
| id | name | password |
+----+-------+----------+
| 1 | admin | admin |
+----+-------+----------+
1 row in set (0.00 sec)
mysql> select * from Role;
+----+----------------------+---------------+----------------+
| id | description | name | summary |
+----+----------------------+---------------+----------------+
| 1 | administrator's role | administrator | Administration |
| 2 | editor's role | editor | Editing |
+----+----------------------+---------------+----------------+
2 rows in set (0.00 sec)
這是創建的聯接表:
mysql> select * from User_Role;
+---------+----------+
| User_id | roles_id |
+---------+----------+
| 1 | 1 |
| 1 | 2 |
+---------+----------+
2 rows in set (0.00 sec)
這是orm.xml
的子集,用於定義表和關系:
<entity class="User" name="User">
<table name="User" />
<attributes>
<id name="id">
<generated-value strategy="AUTO" />
</id>
<basic name="name">
<column name="name" length="100" unique="true" nullable="false"/>
</basic>
<basic name="password">
<column length="255" nullable="false" />
</basic>
<one-to-many
name="roles"
fetch="EAGER"
target-entity="Role"
/>
</attributes>
</entity>
<entity class="Role" name="Role">
<table name="Role" />
<attributes>
<id name="id">
<generated-value strategy="AUTO"/>
</id>
<basic name="name">
<column name="name" length="40" unique="true" nullable="false"/>
</basic>
<basic name="summary">
<column name="summary" length="100" nullable="false"/>
</basic>
<basic name="description">
<column name="description" length="255"/>
</basic>
</attributes>
</entity>
但是,盡管如此,當我檢索管理員用戶時,我還是得到了一個空集合。 我使用Hibernate作為我的JPA提供程序,它顯示以下調試SQL:
select
user0_.id as id8_,
user0_.name as name8_,
user0_.password as password8_
from
User user0_
where
user0_.name=? limit ?
延遲加載一對多映射時,這是唯一進行的查詢。 這將正確檢索一個管理員用戶。 我更改了關系以使用緊急加載,然后除了上述內容之外還進行了以下查詢:
select
roles0_.User_id as User1_1_,
roles0_.roles_id as roles2_1_,
role1_.id as id9_0_,
role1_.description as descript2_9_0_,
role1_.name as name9_0_,
role1_.summary as summary9_0_
from
User_Role roles0_
left outer join
Role role1_
on roles0_.roles_id=role1_.id
where
roles0_.User_id=?
結果如下:
+----------+-----------+--------+----------------------+---------------+----------------+
| User1_1_ | roles2_1_ | id9_0_ | descript2_9_0_ | name9_0_ | summary9_0_ |
+----------+-----------+--------+----------------------+---------------+----------------+
| 1 | 1 | 1 | administrator's role | administrator | Administration |
| 1 | 2 | 2 | editor's role | editor | Editing |
+----------+-----------+--------+----------------------+---------------+----------------+
2 rows in set (0.00 sec)
Hibernate顯然知道角色,但是getRoles()
仍然返回一個空集合。 Hibernate還認識到這種關系足以將數據放在首位。
什么問題會導致這些症狀?
對我而言,您的物理模型與實體的映射之間存在某種不匹配:物理模型實現了多對多關系(帶有連接表),而映射則聲明了一對多關系。 IMO,物理模型是“正確的”:一個用戶可以具有多個角色,一個角色可以與多個用戶相關聯。 換句話說,用戶和角色之間的關系是多對多的。
好的,我發現了導致問題的幾種不同症狀:
多對多映射也可以。 最終結果如下所示:
<entity class="User" name="User">
<table name="User" />
<attributes>
<id name="id">
<generated-value strategy="AUTO" />
</id>
<basic name="name">
<column name="name" length="100" unique="true" nullable="false"/>
</basic>
<basic name="password">
<column length="255" nullable="false" />
</basic>
<many-to-many
name="roles"
fetch="EAGER"
target-entity="Role"
/>
</attributes>
</entity>
<entity class="Role" name="Role">
<table name="Role" />
<attributes>
<id name="id">
<generated-value strategy="AUTO"/>
</id>
<basic name="name">
<column name="name" length="40" unique="true" nullable="false"/>
</basic>
<basic name="summary">
<column name="summary" length="100" nullable="false"/>
</basic>
<basic name="description">
<column name="description" length="255"/>
</basic>
<many-to-many
name="users"
mapped-by="roles"
/>
</attributes>
</entity>
事實證明,這兩種解決方案都可以,但是多對多解決方案假定我的角色對象中有一個字段,該字段允許我查詢(和/或設置)用戶。 這將使角色管理更加容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.