簡體   English   中英

Hibernate(使用Spring)多對多查詢

[英]Hibernate (using Spring) query with many-to-many

我有一個用戶和一個具有多對多關系的 userRole 表。 我有以下 Hibernate 映射:

<hibernate-mapping>
<class name="domain.User" schema="dbo" table="Users">
<id name="userId" type="int">
  <column name="UserId"/>
  <generator class="native"/>
</id>
<property name="username" type="string">
  <column name="Username" not-null="true"/>
</property>
<property name="password" type="string">
  <column name="Password" not-null="true"/>
</property>
<set cascade="all" inverse="true" name="userRole" table="UserRoleRelationships">
  <key>
    <column name="UserId"/>
  </key>
  <many-to-many class="domain.UserRole" column="RoleId" />
</set>
</class>
</hibernate-mapping>

和:

<hibernate-mapping>
<class name="domain.UserRole" schema="dbo" table="UserRoles">
<id name="roleId" type="int">
  <column name="RoleId"/>
  <generator class="native"/>
</id>
<property name="role" type="string">
  <column name="Role" not-null="true"/>
</property>
</class>
</hibernate-mapping>

我的豆子看起來像:

public class User {

private Integer userId;
private String username;
private String password;
private Set<UserRole> userRole;

// getters and setters
}

public class UserRole {

private Integer roleId;
private String role;
private User user;

// getters and setters
}

通過用戶名選擇用戶的查詢如下所示:

public List<User> getWithUsername(String username){
    return getHibernateTemplate().find("from User as u "
            + "inner join fetch u.userRole "
            + "where u.username = '" + username + "'" );
}

問題是當我嘗試使用以下循環打印出來時:

for (User u : list){
            System.out.println(u.getUsername());

            for (UserRole ur : u.getUserRole()){
                System.out.println(ur.getRole());
            }  
        }

它把它加倍打印:

Username: jorgen
User role: User
User role: Admin
Username: jorgen
User role: User
User role: Admin

我究竟做錯了什么? 請幫忙:)

你沒有做錯什么。 Hibernate 就是這樣做的,這與它構建查詢的方式有關。 如果你在 SQL 中做同樣的事情,你也會有兩行。

解決這個問題的一般方法有兩種:

  • 您可以使用DistinctRootEntityProjection但據我所知,它僅適用於標准
  • 您可以自己過濾掉重復項(我建議您將該邏輯封裝在調用您休眠的 class 中)。 最簡單的方法是將您的物品放在一組中並再次取出。

我找到了一個符合標准的解決方案:

public List<User> getWithUsername(String username){

    Criteria criteria = getSession().createCriteria(IWUser.class)
    .add(Restrictions.like("username", username))
    .setFetchMode("userRole", FetchMode.EAGER)
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

    return criteria.list();

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM