简体   繁体   English

通过查询休眠多对多数据

[英]Hibernate many-to-many data retrieval, via query

Please help me, I think there is something that I am not doing correct. 请帮助我,我认为我做的不正确。 I have User and Contact , that are in Many-to-Many relation. 我有“ User和“ Contact ,它们具有Many-to-Many关系。

User.java: User.java:

public class User {

    private Integer userID;

    private String userLoginEmail;

    private Set<Contact> contactSet = new HashSet<Contact>();

    public User() {

    }

    .
    getters and setters
    .

Contact.java Contact.java

public class Contact implements Serializable {
    private Integer contactID;
    private Set<User> userSet= new HashSet<User>();
    public Contact() {
    }
    .
    getters and setters
    .
    .

Mapping for User: 用户映射:

<hibernate-mapping package="com.smallworks.model" schema="projectdb">
 <class name="User" table="USERACCOUNT">
  <id column="USER_ID" length="500" name="userID">
   <generator class="increment"/>
  </id>
  <set cascade="all" fetch="select" lazy="true" name="contactSet"
   sort="unsorted" table="USER_CONTACT">
   <key column="USER_ID"/>
   <many-to-many class="com.smallworks.model.Contact"
    column="CONTACT_ID" order-by="CONTACT_ID" unique="false"/>
  </set>
  </class>
</hibernate-mapping>

Mapping for Contact: 映射联系人:

<hibernate-mapping package="com.smallworks.model" schema="projectdb">
 <class name="Contact" table="CONTACT">
  <id column="CONTACT_ID" length="500" name="contactID">
   <generator class="increment"/>
  </id>
  <!-- many to many mapping with the User via User_Contact table -->
  <set inverse="true" lazy="false" name="userSet" sort="unsorted" table="USER_CONTACT">
    <key column="USER_ID"/>
    <many-to-many class="com.smallworks.model.Contact" column="CONTACT_ID" unique="false"/>
  </set>
 </class>
</hibernate-mapping>

I am trying to write a query to get the Contacts associated with the User that is logged in. 我正在尝试编写查询以获取与登录User相关联的Contacts

When I try to write the following query: 当我尝试编写以下查询时:

Query query=session.createQuery("select contact from com.src.model.Contact  contact join contact.userSet u where u.userID=:userID");
        query.setParameter("userID", user.getUserID());
        contactList=query.list();

I get the following error: 我收到以下错误:

org.hibernate.QueryException: could not resolve property: userID of: com.src.model.Contact [select contact from com.src.model.Contact  contact join contact.userSet u where u.userID=:userID]

I know what the error message means, but I am not being able to figure out how to write this query. 我知道错误消息的含义,但是我无法弄清楚如何编写此查询。

First I did like this: Hibernate many-to-many data retrieval 首先,我确实是这样的: 休眠多对多数据检索

but now I am writing a query because I need to check on the Contact status, and other parameters. 但是现在我正在写查询,因为我需要检查Contact状态和其他参数。

Thanks Harbir 谢谢哈比尔

This is how I am calling the query: 这就是我调用查询的方式:

@Override
    public List<Contact> getContactList(User user) {
        log.info("getContactList(User user)");
        List contactList = new ArrayList();
        Session session = sessionFactory.getCurrentSession();
        System.out.println("About to hit the query");
        Query query=session.createQuery("select contact from com.smallworks.model.Contact  contact join contact.userSet u where u.userID=:userID");
        query.setParameter("userID", user.getUserID());
        contactList=query.list();
        return contactList;
    }

The following is the stack trace: 以下是堆栈跟踪:

About to hit the query
18:56:01.011 [http-bio-8080-exec-6] DEBUG o.h.hql.ast.QueryTranslatorImpl - parse() - HQL: select contact from com.smallworks.model.Contact  contact join contact.userSet u where u.userID=:userID
18:56:01.020 [http-bio-8080-exec-6] DEBUG org.hibernate.hql.ast.AST - --- HQL AST ---
 \-[QUERY] 'query'
    +-[SELECT_FROM] 'SELECT_FROM'
    |  +-[FROM] 'from'
    |  |  +-[RANGE] 'RANGE'
    |  |  |  +-[DOT] '.'
    |  |  |  |  +-[DOT] '.'
    |  |  |  |  |  +-[DOT] '.'
    |  |  |  |  |  |  +-[IDENT] 'com'
    |  |  |  |  |  |  \-[IDENT] 'smallworks'
    |  |  |  |  |  \-[IDENT] 'model'
    |  |  |  |  \-[IDENT] 'Contact'
    |  |  |  \-[ALIAS] 'contact'
    |  |  \-[JOIN] 'join'
    |  |     +-[DOT] '.'
    |  |     |  +-[IDENT] 'contact'
    |  |     |  \-[IDENT] 'userSet'
    |  |     \-[ALIAS] 'u'
    |  \-[SELECT] 'select'
    |     \-[IDENT] 'contact'
    \-[WHERE] 'where'
       \-[EQ] '='
          +-[DOT] '.'
          |  +-[IDENT] 'u'
          |  \-[IDENT] 'userID'
          \-[COLON] ':'
             \-[IDENT] 'userID'

18:56:01.020 [http-bio-8080-exec-6] DEBUG org.hibernate.hql.ast.ErrorCounter - throwQueryException() : no errors
18:56:01.041 [http-bio-8080-exec-6] DEBUG o.h.hql.antlr.HqlSqlBaseWalker - select << begin [level=1, statement=select]
18:56:01.050 [http-bio-8080-exec-6] DEBUG o.hibernate.hql.ast.tree.FromElement - FromClause{level=1} :  com.smallworks.model.Contact (contact) -> contact0_
18:56:01.051 [http-bio-8080-exec-6] DEBUG o.h.hql.ast.tree.FromReferenceNode - Resolved :  contact -> contact0_.CONTACT_ID
18:56:01.053 [http-bio-8080-exec-6] DEBUG org.hibernate.hql.ast.tree.DotNode - getDataType() : userSet -> org.hibernate.type.SetType(com.smallworks.model.Contact.userSet)
18:56:01.053 [http-bio-8080-exec-6] DEBUG o.h.hql.ast.tree.FromElementFactory - createManyToMany() : path = contact.userSet role = com.smallworks.model.Contact.userSet associatedEntityName = com.smallworks.model.Contact
18:56:01.055 [http-bio-8080-exec-6] DEBUG o.hibernate.hql.ast.tree.FromElement - FromClause{level=1} :  com.smallworks.model.Contact (u) -> contact2_
18:56:01.055 [http-bio-8080-exec-6] DEBUG o.hibernate.hql.ast.tree.FromClause - addJoinByPathMap() : contact.userSet -> smallworksdb.CONTACT contact2_
18:56:01.055 [http-bio-8080-exec-6] DEBUG org.hibernate.hql.ast.tree.DotNode - dereferenceCollection() : Created new FROM element for contact.userSet : smallworksdb.USER_CONTACT contact2_
18:56:01.055 [http-bio-8080-exec-6] DEBUG o.h.hql.ast.tree.FromReferenceNode - Resolved :  contact.userSet -> .
18:56:01.056 [http-bio-8080-exec-6] DEBUG org.hibernate.hql.ast.HqlSqlWalker - createFromJoinElement() : -- join tree --
 \-[JOIN_FRAGMENT] FromElement: 'smallworksdb.USER_CONTACT contact2_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=u,role=com.smallworks.model.Contact.userSet,tableName=smallworksdb.CONTACT,tableAlias=contact2_,origin=smallworksdb.CONTACT contact0_,colums={contact0_.CONTACT_ID ,className=com.smallworks.model.Contact}}

18:56:01.056 [http-bio-8080-exec-6] DEBUG o.h.hql.ast.tree.FromReferenceNode - Resolved :  contact -> contact0_.CONTACT_ID
18:56:01.060 [http-bio-8080-exec-6] DEBUG o.h.hql.ast.tree.FromReferenceNode - Resolved :  u -> contact2_.CONTACT_ID
18:56:01.060 [http-bio-8080-exec-6] DEBUG o.s.w.s.m.a.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [com.smallworks.controller.ProjectController@1f183871]: org.hibernate.QueryException: could not resolve property: userID of: com.smallworks.model.Contact [select contact from com.smallworks.model.Contact  contact join contact.userSet u where u.userID=:userID]
18:56:01.062 [http-bio-8080-exec-6] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [com.smallworks.controller.ProjectController@1f183871]: org.hibernate.QueryException: could not resolve property: userID of: com.smallworks.model.Contact [select contact from com.smallworks.model.Contact  contact join contact.userSet u where u.userID=:userID]
18:56:01.062 [http-bio-8080-exec-6] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [com.smallworks.controller.ProjectController@1f183871]: org.hibernate.QueryException: could not resolve property: userID of: com.smallworks.model.Contact [select contact from com.smallworks.model.Contact  contact join contact.userSet u where u.userID=:userID]
18:56:01.069 [http-bio-8080-exec-6] DEBUG o.s.web.servlet.DispatcherServlet - Could not complete request
org.hibernate.QueryException: could not resolve property: userID of: com.smallworks.model.Contact [select contact from com.smallworks.model.Contact  contact join contact.userSet u where u.userID=:userID]
    at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:67) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:61) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1385) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.persister.collection.AbstractCollectionPersister.toType(AbstractCollectionPersister.java:1457) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.FromElementType.getPropertyType(FromElementType.java:302) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.FromElement.getPropertyType(FromElement.java:407) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.DotNode.getDataType(DotNode.java:589) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.DotNode.prepareLhs(DotNode.java:264) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.DotNode.resolve(DotNode.java:211) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:117) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:113) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:750) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1216) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4041) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3525) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1762) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:776) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:577) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:281) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:229) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:251) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:134) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:94) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1650) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
    at com.smallworks.dao.impl.ContactDAOImpl.getContactList(ContactDAOImpl.java:92) [ContactDAOImpl.class:na]
    at com.smallworks.service.impl.ContactServiceImpl.getContactList(ContactServiceImpl.java:95) [ContactServiceImpl.class:na]
    at com.smallworks.controller.ProjectController.addContact(ProjectController.java:117) [ProjectController.class:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.6.0_33]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) [na:1.6.0_33]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [na:1.6.0_33]
    at java.lang.reflect.Method.invoke(Unknown Source) [na:1.6.0_33]
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) [spring-webmvc-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) [servlet-api.jar:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) [servlet-api.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [catalina.jar:7.0.33]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.33]
    at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) [spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [catalina.jar:7.0.33]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.33]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [catalina.jar:7.0.33]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [catalina.jar:7.0.33]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [catalina.jar:7.0.33]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) [catalina.jar:7.0.33]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [catalina.jar:7.0.33]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931) [catalina.jar:7.0.33]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.33]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [catalina.jar:7.0.33]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) [tomcat-coyote.jar:7.0.33]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) [tomcat-coyote.jar:7.0.33]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) [tomcat-coyote.jar:7.0.33]
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) [na:1.6.0_33]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.6.0_33]
    at java.lang.Thread.run(Unknown Source) [na:1.6.0_33]
18:56:01.069 [http-bio-8080-exec-6] DEBUG o.s.o.h.s.OpenSessionInViewFilter - Closing single Hibernate Session in OpenSessionInViewFilter
18:56:01.069 [http-bio-8080-exec-6] DEBUG o.s.o.hibernate3.SessionFactoryUtils - Closing Hibernate Session

In the XML mapping Contact, the mapping of userSet is completely wrong: 在XML映射联系人中,userSet的映射完全错误:

<hibernate-mapping package="com.smallworks.model" schema="projectdb">
 <class name="Contact" table="CONTACT">
  <!-- ... --->
  <set inverse="true" lazy="false" name="userSet" sort="unsorted" table="USER_CONTACT">
    <key column="USER_ID"/>
    <many-to-many class="com.smallworks.model.Contact" column="CONTACT_ID" unique="false"/>
  </set>
 </class>
</hibernate-mapping>

It should be: 它应该是:

  <set inverse="true" lazy="false" name="userSet" sort="unsorted" table="USER_CONTACT">
    <key column="CONTACT_ID"/>
    <many-to-many class="com.smallworks.model.User" column="USER_ID" unique="false"/>
  </set>

It looks to me like you copy-and-pasted this from User and then didn't update it. 在我看来,您好像从User复制并粘贴了此内容,然后没有对其进行更新。

Why are you using XML rather than annotations? 为什么要使用XML而不是注释? XML is much more error-prone, as you can see. 如您所见,XML更容易出错。 In addition, a lot of these settings should be defaulted correctly by Hibernate. 另外,许多这些设置应该由Hibernate正确地默认。 If you had just left out some of these attributes, it probably would have worked fine. 如果您只是省略了其中一些属性,则可能效果很好。

Let's see if I understood right. 让我们看看我是否理解正确。 You want to "get the Contacts associated with the User that is logged in." 您要“获取与已登录用户关联的联系人”。 "I need to check on the Contact status...", correct? “我需要检查联系状态...”,对吗?

If that is the case, try writing the query the other way around. 如果是这种情况,请尝试以其他方式编写查询。 So, you can start with the same query you have here . 因此,您可以从此处的相同查询开始。 Let's suppose you want "All contacts with status 'ACTIVE' for the User that is logged in". 假设您想要“已登录用户的所有状态为“ ACTIVE”的联系人”。

// First, retrieve the user you want.
User user = (User) session.get(User.class, user_id_you_want);
// Return only the conctats with status 'ACTIVE' 
List result = new ArrayList();
for(Contact c : contacts){
  if(c.getStatus().equals("ACTIVE")){
    result.add(c);
  }
}
return result;

I hope it helps... 希望对您有帮助...

===UPDATE1=== === UPDATE1 ===

You are right, I thought a user would have a few contacts. 没错,我认为一个用户会有几个联系人。 How about if you try something like: 如果您尝试类似的操作:

"FROM com.smallworks.model.User as u LEFT JOIN u.contacts as c WHERE u.userId=:userId AND c.status=:status"

Note that you may start your statement with "FROM" instead of "SELECT". 请注意,您可以使用“ FROM”而不是“ SELECT”开始语句。 See some good examples in this tutorial . 请参阅本教程中的一些很好的示例。

Another important reference: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html 另一个重要参考: http : //docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html

Additionally, note that in your case the class User owns the relationship, some statements need to take the ownership in consideration. 另外,请注意,在您的情况下,类User拥有该关系,某些语句需要考虑所有权。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM