如何在Hibernate中的@Formula中编写复杂查询,或者在hibernate中将派生值发送到UI的最佳方法是什么?

时间:2017-10-05 21:10:22

标签: sql hibernate hql

我在方法中有这个查询但在@Formula下。基本上这个方法需要转换为ui中的派生列进行排序

如何在计算字段上对primefaces lazy数据表进行排序。

public Double getTaxAmount() {
        return new BigDecimal(getNetAmount() + (getNetAmount() * (taxRate != null ? taxRate.getRate() : 0))).setScale(2, RoundingMode.HALF_DOWN).doubleValue();
    }

我如何查询

@MappedSuperclass
public abstract class Bill extends IdentityEntity {


    @Column(name = "AMOUNT")
    @Setter
    private Double amount;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TAX_ID")
    @Getter
    @Setter
    private TaxRate taxID;

    @Formula( "(SELECT
        invc.ID as ID,
        (invc.NET_NET_AMOUNT + ( invc.NET_NET_AMOUNT * ISNULL(tx.RATE,0) )) AS TAX_INCLUDED_AMOUNT
        FROM INVOICE invc
        left join TAX_RATE tx on invc.TAX_RATE_ID = tx.ORIGINAL_TAX_RATE_ID)")
    @Getter
    private Double totalAmount;

    public Double getNetAmount() {
        return amount;
    }

    public Double getTaxAmount() {
        return new BigDecimal(getNetAmount() + (getNetAmount() * (taxID != null ? taxID.getRate() : 0))).setScale(2, RoundingMode.HALF_DOWN).doubleValue();
    }
}

发票扩展了Bill,在UI上显示了Invoice。

    @Entity
    @Table(name = "INVOICE")
    @Audit(of = {"number"})
    public class Invoice extends Bill{

        @Column
        ...
    }

税率表

@Entity
@Table(name = "TAX_RATE")
public class TaxRate extends Name implements Serializable {

    @Column(name = "CODE")
    @Getter
    @Setter
    private String code;

    @Column(name = "TAX_ID", insertable = false, updatable = false)
    @Getter
    @Setter
    private Long taxId;

    @Column(name = "RATE")
    @Getter
    @Setter
    private Double rate;

    }
到目前为止,我有:

  @Formula( "(SELECT
        invc.ID as ID,
        (invc.NET_NET_AMOUNT + ( invc.NET_NET_AMOUNT * ISNULL(tx.RATE,0) )) AS TAX_INCLUDED_AMOUNT
        FROM INVOICE invc
        left join TAX_RATE tx on invc.TAX_RATE_ID = tx.ORIGINAL_TAX_RATE_ID)")

但它不起作用。或者我可以用列名

写@Formula

(AMOUNT+(AMOUNT* ISNULL(TAXRATE.RATE,0)))。这样的事情。

<p:column styleClass="amountColumn" sortBy="#{item.totalAmount}">
...
</p:column>

所以当我打电话点击排序。它给出了一个错误:

  invoice0_.PURCHASE_ORDER_NUMBER 
as PURCHASE_ORDER_NUMBER103_143_, invoice0_.REMARK as REMARK104_143_, invoice0_.SENT as SENT105_143_, 
invoice0_.SORT_NUMBER as SORT_NUMBER106_143_, invoice0_.WEBSITE_ID as WEBSITE_ID122_143_, (SELECT
  invc.ID as ID,  (invc.NET_NET_AMOUNT + ( invc.NET_NET_AMOUNT * ISNULL(tx.RATE,0) )) 
FROM INVOICE invc left join TAX_RATE tx on invc.TAX_RATE_ID = tx.ORIGINAL_TAX_RATE_ID) as formula0_ 
from INVOICE invoice0_ where (invoice0_.REPFIRM_ID in (1)) and invoice0_.INVOICE_DATE>='06/02/2017 
00:00:00.000' and invoice0_.INVOICE_DATE<='10/02/2017 23:59:59.000' order by (select sum(oe.NET_NET_AMOUNT) 
from ORDER_ELEMENT oe where oe.ORDER_ID = invoice0_.ID) asc  {FAILED after 39 ms}
java.sql.SQLException: Subqueries are not allowed in an ORDER BY clause.

        at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:372) ~[jtds-1.3.1.jar:1.3.1]
        at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2988) ~[jtds-1.3.1.jar:1.3.1]
        at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2421) ~[jtds-1.3.1.jar:1.3.1]
        at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:671) ~[jtds-1.3.1.jar:1.3.1]
        at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:505) ~[jtds-1.3.1.jar:1.3.1]
        at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:1029) ~[jtds-1.3.1.jar:1.3.1]
        at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83) ~[commons-dbcp2-2.1.1.jar:2.1.1]
        at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83) ~[commons-dbcp2-2.1.1.jar:2.1.1]
        at net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy.executeQuery(PreparedStatementSpy.java:621) [log4jdbc-log4j2-jdbc3-1.16.jar:?]
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.getResultSet(Loader.java:2066) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.doQuery(Loader.java:910) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.doList(Loader.java:2554) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.doList(Loader.java:2540) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.Loader.list(Loader.java:2365) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:67) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.readPage(SimpleJpaRepository.java:472) [spring-data-jpa-1.7.2.RELEASE.jar:?]
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:370) [spring-data-jpa-1.7.2.RELEASE.jar:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_131]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:416) [spring-data-commons-1.9.2.RELEASE.jar:?]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:401) [spring-data-commons-1.9.2.RELEASE.jar:?]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373) [spring-data-commons-1.9.2.RELEASE.jar:?]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:486) [spring-data-commons-1.9.2.RELEASE.jar:?]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) [spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122) [spring-data-jpa-1.7.2.RELEASE.jar:?]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) [spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
        at com.sun.proxy.$Proxy166.findAll(Unknown Source) [?:?]
        at com.wideorbit.fivia.web.model.SpecSearchLazyEntityDataModel.findEntities(SpecSearchLazyEntityDataModel.java:35) [classes/:?]
        at com.wideorbit.fivia.web.model.LazyEntityDataModel.load(LazyEntityDataModel.java:71) [classes/:?]
        at org.primefaces.component.datatable.DataTable.loadLazyData(DataTable.java:841) [primefaces-5.1.jar:5.1]
        at org.primefaces.component.datatable.feature.SortFeature.encode(SortFeature.java:99) [primefaces-5.1.jar:5.1]
        at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:78) [primefaces-5.1.jar:5.1]
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:920) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:582) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) [javax.faces-2.2.13.jar:2.2.13]
        at org.primefaces.component.api.UIData.visitTree(UIData.java:692) [primefaces-5.1.jar:5.1]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIForm.visitTree(UIForm.java:371) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:322) [javax.faces-2.2.13.jar:2.2.13]
        at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) [primefaces-5.1.jar:5.1]
        at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:432) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:134) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [javax.faces-2.2.13.jar:2.2.13]
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [javax.faces-2.2.13.jar:2.2.13]
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219) [javax.faces-2.2.13.jar:2.2.13]
        at org.springframework.faces.support.LifecycleWrapper.render(LifecycleWrapper.java:54) [spring-faces-2.4.1.RELEASE.jar:2.4.1.RELEASE]
        at org.springframework.faces.webflow.JsfView.render(JsfView.java:87) [spring-faces-2.4.1.RELEASE.jar:2.4.1.RELEASE]
        at org.springframework.webflow.engine.ViewState.render(ViewState.java:293) [spring-webflow-2.4.2.RELEASE.jar:2.4.2.RELEASE]
        at org.springframework.webflow.engine.ViewState.resume(ViewState.java:206) [spring-webflow-2.4.2.RELEASE.jar:2.4.2.RELEASE]
        at org.springframework.webflow.engine.Flow.resume(Flow.java:537) [spring-webflow-2.4.2.RELEASE.jar:2.4.2.RELEASE]

我对Hibernate相当新,我不明白我做错了什么?为什么不允许子查询?有一些我不知道的东西。请帮忙。

编辑:即使我提出此查询,它也会抛出相同的错误。

@Formula("(select sum(oe.NET_NET_AMOUNT) from INVOICE oe where oe.ID = ID)")

1 个答案:

答案 0 :(得分:0)

select sum(oe.amount,(oe.amount* isnull(oe.taxrate,0))) from order oe

Order是一个SQL保留字,只需更改您的表名,不会抛出此异常

java.sql.SQLException: Subqueries are not allowed in an ORDER BY clause.