HQL query - pulling data through a join relationship
I am having trouble with a relatively simple HQL query being called from a jsp page through a javaBean. I am just setting things up for testing at the moment to make sure I know how to do everything before I get all crazy with my pages.
The issue I am having (beyond not knowing exactly what I'm doing of course) is the function getHighBidder is not working properly. As stated below, Bid is a join between User and Item. I want to have an itemID and use it to look up the maximum bidAmt from the Bid table and return the UserID or User object associated with the bid. However, when I run the function in my current setup, it returns null and I always end up with my error "Failed to find high bidder for Item".
I've tried both queries (one is commented out) in the getHighBidder function in the HQL query editor in NetBeans and it successfully returns the User instance that matches the highest bid for the specified item. This is why I'm so confused why I'm getting a null values when I actually test the query in jsp.
I've been dealing with this for a couple days now and can't seem to get anywhere. Any help, hints, pointers, or advice on good learning tools or references would be extremely appreciated. I feel like once I get this problem solved, I'll be able to created almost all of the functions I need for my project.
---EDIT--- Here is the error netBeans spits at me:
at org.hibernate.hql.classic.PathExpressionParser.token(PathExpressionParser.java:130)
at org.hibernate.hql.classic.ParserHelper.parse(ParserHelper.java:28)
at org.hibernate.hql.classic.SelectParser.token(SelectParser.java:176)
at org.hibernate.hql.classic.ClauseParser.token(ClauseParser.java:86)
at org.hibernate.hql.classic.ClauseParser.end(ClauseParser.java:113)
at org.hibernate.hql.classic.PreprocessingParser.end(PreprocessingParser.java:122)
at org.hibernate.hql.classic.ParserHelper.parse(ParserHelper.java:29)
at org.hibernate.hql.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:216)
at org.hibernate.hql.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:185)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at $Proxy59.createQuery(Unknown So开发者_StackOverflowurce)
at GavelDB.GavelDBHelper.getHighBidder(GavelDBHelper.java:99)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:109)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:864)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1600)
Here is part of the JSP page I am using to call the bean:
<jsp:useBean id="test" class="GavelDB.GavelDBHelper" scope="page">
<%
...
user = test.getHighBidder(item.getItemId());
if(user == null)
out.println("Failed to find high bidder for Item");
else
out.println("Successfully selected User Number " + user.getUserId() + ": " + user.getUserName());
%>
Here is the bean that is being called. Note that getItemByID works just fine with my current setup, returning the Item object for use in the jsp page.
public class GavelDBHelper
{
Session session = null;
...
public Item getItemByID(int itemID)
{
Item item = null;
try
{
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery (
"from Item as item where item.id = '" + itemID + "'");
item = (Item)q.uniqueResult();
} catch (Exception e)
{
e.printStackTrace();
}
return item;
}
public User getHighBidder(int itemID)
{
User highBidder = null;
try
{
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery (
"select user" +
"from User as user, Bid as bid" +
"where user.id = bid.user.id and bid.bidAmt in(" +
"select max(b.bidAmt)" +
"from Bid as b" +
"where b.item.id = '" + itemID + "')");
/*Query q = session.createQuery (
"select bid.user"+
"from Bid as bid"+
"where bid.bidAmt in("+
"select max(b.bidAmt)"+
"from Bid as b"+
"where b.item.id = '"+ itemID +"')");*/
highBidder = (User)q.uniqueResult();
} catch (Exception e)
{
e.printStackTrace();
}
return highBidder;
}
...
}
I have the following database design:
=====================================================User table: <br>
PK USER_ID, <br>
USER_NAME UNIQUE, <br>
...
Item table: <br>
PK ITEM_ID, <br>
FK ITEM_SELLER -> Many to One relationship with user.USER_ID, <br>
FK ITEM_BUYER -> Many to One relationship with user.USER_ID, <br>...
Bid table (bridge between user and item): <br>
PK BID_ID, <br>
FK BIDDER_ID -> Many to One relationship with user.USER_ID, <br>
FK ITEM_ID -> Many to One relationship with item.ITEM_ID, <br>...
If you look at the stack trace you will see the error is occurring when Hibernate is processing your query string.
Looking at this:
Query q = session.createQuery (
"select user" +
"from User as user, Bid as bid" +
"where user.id = bid.user.id and bid.bidAmt in(" +
"select max(b.bidAmt)" +
"from Bid as b" +
"where b.item.id = '" + itemID + "')");
You have no whitespace between the strings you are concatenating so the query string you are constructing would look like:
select *userfrom* User as user, Bid as *bidwhere* user.id = bid.user.id and bid.bidAmt *in(select max(b.bidAmt)from* Bid as *bwhere* b.item.id ...
and hence hibernate is throwing an exception when it tries to parse it.
Hope that helps!
Kate.
精彩评论