java Hibernate Joins using Criteria
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12251112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate Joins using Criteria
提问by m0rv4i
I am trying to use Hibernate to access persisted data for our rights management, but I am very new to it and struggling to get the data I need.
我正在尝试使用 Hibernate 访问持久数据以进行我们的权限管理,但我对它很陌生并且正在努力获取我需要的数据。
I have Users table, with an ID and name, a Groups table with an ID and name, and a User/Groups mapping which just consists of the group ids and user ids that are linked.
我有一个带有 ID 和名称的用户表,一个带有 ID 和名称的组表,以及一个仅由链接的组 ID 和用户 ID 组成的用户/组映射。
What I want to do is get all the names of the members of a given group, so the standard SQL query I want to execute is this:
我想要做的是获取给定组成员的所有名称,因此我要执行的标准 SQL 查询是这样的:
SELECT
u.NAME
FROM
USERS u
JOIN
GROUP_USERS gu
ON
u.ID = gu.USER_ID
JOIN
GROUPS g
ON
gu.GROUP_ID = g.ID
WHERE
g.NAME = 'test'
But despite hours of looking and playing I cannot seem to get anywhere.
但是,尽管经过数小时的观看和玩耍,我似乎无处可去。
I want to use Criteria as they seem clearer, so my code is as follows:
我想使用 Criteria ,因为它们看起来更清晰,所以我的代码如下:
@Override
public final List<String> getGroupMembers(final String groupName) {
@SuppressWarnings("unchecked")
List<User> groupUsers = getHibernateTemplate().execute(new HibernateCallback<List<User>>() {
@Override
public List<User> doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(User.class)
.setFetchMode("GroupUsers", FetchMode.JOIN)
.setFetchMode("Group", FetchMode.JOIN)
.add(Restrictions.eq("name", groupName));
return criteria.list();
}
});
List<String> groupUsernames = new ArrayList<String>();
for (User groupUser : groupUsers) {
groupUsernames.add(groupUser.getName());
}
return groupUsernames;
}
But when I test it the result set is empty, and according to the logs the executed query is this:
但是当我测试它时,结果集是空的,根据日志,执行的查询是这样的:
select this_.ID as M1_4_0_, this_.NAME as M2_4_0_ from USERS this_ where this_.NAME=?
I let Hibernate create the tables using hibernate.hbm2ddl.auto, but then removed it so that the tables are definitely as hibernate expects, but the data is not being cleaned.
我让 Hibernate 使用 hibernate.hbm2ddl.auto 创建表,但随后将其删除,以便表绝对符合 hibernate 的预期,但数据并未被清理。
Any help with the Criteria would be greatly appreciated, so thanks in advance!
对标准的任何帮助将不胜感激,所以提前致谢!
Edit: I am using xml mapping files:
编辑:我正在使用 xml 映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.company">
<class name="com.company.Group" table="GROUPS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
and
和
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.company">
<class name="com.company.GroupUsers" table="GROUP_USERS">
<composite-id>
<key-many-to-one name="groupId" class = "Group" column="GROUP_ID" />
<key-many-to-one name="userId" class = "User" column="USER_ID" />
</composite-id>
</class>
</hibernate-mapping>
and
和
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.company">
<class name="com.company.User" table="USERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
回答by kothvandir
You don't need to map the user-group table, just define your relation between User and Group as a many-to-many relation, take a look at thisand thisabout how to map many-to-many relations.
您不需要映射用户组表,只需将用户和组之间的关系定义为多对多关系,看看this和this关于如何映射多对多关系。
In your case, it will look like:
在你的情况下,它看起来像:
<hibernate-mapping package="com.company">
<class name="com.company.User" table="USERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
<many-to-many name="userGroups"
target-entity="com.company.Group">
<join-table name="YOUR_USER_GROUP_TABLE">
<join-column name="USER_ID" />
<inverse-join-column name="GROUP_ID" />
</join-table>
</many-to-many>
</class>
And to filter your users using the name field from the Group entity for example:
并使用 Group 实体中的 name 字段过滤您的用户,例如:
Criteria criteria = session.createCriteria(User.class);
criteria.createAlias("userGroups", "usrGrp",CriteriaSpecification.LEFT_JOIN);
criteria.add( Restrictions.eqProperty("usrGrp.name", "test") )
回答by Vlad
The way you map your object to tables does not benefit from the usage of Hibernate as ORM. Consider a more object-oriented model, eg:
将对象映射到表的方式不会从将 Hibernate 用作 ORM 中受益。考虑一个更面向对象的模型,例如:
class Group {
private Set<User> users;
// ...
}
class User {
private Set<Group> groups;
//..
}
So, you've got a classical many-to-many association. Hereyou can find an example of such mapping with Hibernate.
所以,你有一个经典的多对多关联。在这里您可以找到使用 Hibernate 进行此类映射的示例。