Проблема языка запросов Hibernate - PullRequest
1 голос
/ 11 июня 2010

Ну, я реализовал отдельный запрос в спящем режиме. Это возвращает мне результат. Но во время кастинга поля меняются местами. Таким образом, он генерирует ошибку приведения. Каким должно быть решение?

Например, у меня есть база данных "ProjectAssignment", которая имеет три поля: aid, pid и userName. Я хочу, чтобы все различные данные userName из этой таблицы Я применил запрос:

select distinct userName, aid, pid from ProjectAssignment

Принимая во внимание, что файл ProjectAssignment.java имеет поля в последовательности помощи, pid & userName. Теперь здесь userName является первым полем в выводе. Итак, кастинг невозможен.

Также запрос:

select aid, pid, distinct userName from ProjectAssignment

не работает.

Какой правильный запрос для того же? Или какое еще решение?

Код следующий:

Метод EJB, при котором мне нужно получить данные:

public List<ProjectAssignment> getProjectAssignments() {
        projectAssignments = ProjectAssignmentHelper.getAllResources(); //Here comes the error
        return projectAssignments;
    }

ProjectAssignmentHelper откуда я беру данные:

package com.hibernate;

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;

public class ProjectAssignmentHelper {

    public static List<ProjectAssignment> getAllResources() {
        List<ProjectAssignment> projectMasters;

        Session session = HibernateUtil.getSessionFactory().openSession();
        Query query = session.createQuery("select distinct aid, pid, userName from ProjectAssignment");
        projectMasters = (List<ProjectAssignment>) query.list();
        session.close();

        return projectMasters;
    }
}

Hibernate Data Bean:

package com.hibernate;

public class ProjectAssignment  implements java.io.Serializable {

     private short aid;
     private String pid;
     private String userName;

    public ProjectAssignment() {
    }


    public ProjectAssignment(short aid) {
        this.aid = aid;
    }
    public ProjectAssignment(short aid, String pid, String userName) {
       this.aid = aid;
       this.pid = pid;
       this.userName = userName;
    }

    public short getAid() {
        return this.aid;
    }

    public void setAid(short aid) {
        this.aid = aid;
    }
    public String getPid() {
        return this.pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }
    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

Ошибка:

Для входной строки: "userName"

java.lang.NumberFormatException: For input string: "userName"
 at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
 at java.lang.Integer.parseInt(Integer.java:447)
 at java.lang.Integer.parseInt(Integer.java:497)
 at javax.el.ArrayELResolver.toInteger(ArrayELResolver.java:375)
 at javax.el.ArrayELResolver.getValue(ArrayELResolver.java:195)
 at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
 at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
 at com.sun.el.parser.AstValue.getValue(AstValue.java:116)
 at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
 at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
 at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
 at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
 at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
 at javax.faces.component.UICommand.getValue(UICommand.java:218)
 at org.primefaces.component.commandlink.CommandLinkRenderer.encodeMarkup(CommandLinkRenderer.java:113)
 at org.primefaces.component.commandlink.CommandLinkRenderer.encodeEnd(CommandLinkRenderer.java:54)
 at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
 at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:70)
 at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:54)
 at org.primefaces.component.datatable.DataTableRenderer.encodeTable(DataTableRenderer.java:525)
 at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:407)
 at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:193)
 at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
 at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:70)
 at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:54)
 at org.primefaces.component.tabview.TabViewRenderer.encodeContents(TabViewRenderer.java:198)
 at org.primefaces.component.tabview.TabViewRenderer.encodeMarkup(TabViewRenderer.java:130)
 at org.primefaces.component.tabview.TabViewRenderer.encodeEnd(TabViewRenderer.java:48)
 at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
 at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
 at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
 at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
 at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
 at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
 at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
 at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:802)
 at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:664)
 at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:497)
 at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:468)
 at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:364)
 at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:314)
 at org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:783)
 at org.apache.jsp.welcome_jsp._jspService(welcome_jsp.java from :59)
 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
 at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:406)
 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:483)
 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:373)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
 at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
 at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
 at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
 at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
 at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
 at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
 at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
 at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
 at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
 at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
 at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
 at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
 at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
 at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
 at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
 at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
 at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
 at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
 at java.lang.Thread.run(Thread.java:619)

Ответы [ 3 ]

3 голосов
/ 15 июня 2010
Query query = session.createQuery("select distinct aid, pid, userName from ProjectAssignment");

На самом деле query.list () будет возвращать экземпляр ArrayList, содержащий Array of Objects в качестве каждого элемента. И каждый элемент в массиве содержит значение для каждого столбца.

например. query.list (). get (0) вернет массив из трех объектов

array[0] = value of aid
array[1] = value of pid
array[2] = value of userName

так, List<Object[]> нельзя привести к List<ProjectAssignment>

Одним из возможных решений является реализация ResultTransformer

как то так .........

Сначала скажите Hibernate, какой трансформатор использовать

query.setResultTransformer(new ProjectAssignmentTransformer());

Теперь реализация

class ProjectAssignmentTransformer implements ResultTransformer {

@Override
public Object transformTuple(Object[] tuples, String[] aliases) {
            Object aid = tuples[0];
            Object pid = tuples[1];
            Object userName = tuples[2];
             /* construct ProjectAssignment instance using appropriate args*/
    return new ProjectAssignment (aid, pid, (String) userName);
}

@Override
public List transformList(List collection) {
    List<ProjectAssignment> assignments = new ArrayList<ProjectAssignment>();
    for(Object o : collection)
    {
        assignments.add((ProjectAssignment)o);  
    }
    return assignments;
}

}

После этого вы сможете кастовать на List<ProjectAssignment>.

Надеюсь, это поможет!

-se

2 голосов
/ 11 июня 2010

Прежде всего, если вы используете проекции, как в:

select distinct aid, pid, userName from ProjectAssignment

В результате вы получите Object[] (или List<Object[]>), а не List<ProjectAssignment>. Если вы хотите получить строго типизированные объекты в результате при использовании проекций, вы должны использовать выражение select NEW (при условии, что вы предоставили правильный конструктор):

select new com.hibernate.ProjectAssignment(...) from ProjectAssignment.

Во-вторых, я не понимаю, чего вы на самом деле хотите. Из простого английского описания запрос будет:

select distinct userName from ProjectAssignment

Но я не уверен, что это то, что вы ожидаете. Возможно, если вы укажете простым языком, каков ожидаемый результат, я мог бы помочь в дальнейшем.

В-третьих, текущая проблема НИЧЕГО не имеет отношения к Hibernate или касту:

java.lang.NumberFormatException: For input string: "userName"

Вы просто пытаетесь отформатировать строку, которая не является числом, как число.

0 голосов
/ 11 июня 2010

Почему вы хотите использовать HQL?

Идея Hibernate заключается в работе с сущностями, а не с таблицами. В идеале вы должны загружать объекты и проходить по ним, получая нужные поля.

Я бы предложил вам использовать Критерии и Критерии гибернации для этого запроса.

Criteria crit = session.createCriteria(ProjectAssignment.class);
List projectAssignments = crit.list();

А затем выполните итерацию по списку, получая нужные поля.

...