从Hibernate 5.x迁移到6.2,许多以前工作的东西现在都失败了

vlju58qv  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(454)

我需要帮助解决我从Hibernate 5.x迁移到6.2后遇到的问题。以前一直没有任何问题的代码现在失败了。下面是一个失败的查询示例。

public List<MarketCommodityInfo> getMarketCommodityInfoForCommodities(Double longitude, Double latitude,
            Integer page) {

        return getEntityManager().createQuery(
                "SELECT new org.kisanag.model.mandi.MarketCommodityInfo (mci, earth_distance(ll_to_earth(m.latitude, m.longitude), ll_to_earth(:latitude, :longitude)) / :conversion AS distance) FROM MarketCommodityInfo mci JOIN mci.id.market m JOIN mci.id.commodity c WHERE earth_distance(ll_to_earth(m.latitude, m.longitude),ll_to_earth(:latitude, :longitude)) < :within * :conversion ORDER BY distance, mci.id.arrivalDate, c.name",
                MarketCommodityInfo.class)
                .setParameter("latitude", latitude)
                .setParameter("longitude", longitude)
                .setParameter("within", 200)
                .setParameter("conversion", 1000)
                .setMaxResults(pageSize)
                .setFirstResult(page * pageSize)
                .getResultList();

    }

此操作因错误而失败

Caused by: java.lang.IllegalStateException: Could not determine appropriate instantiation strategy - no matching constructor found and one or more arguments did not define alias for bean-injection
        at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationResultImpl.resolveAssembler(DynamicInstantiationResultImpl.java:197)
        at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationResultImpl.createResultAssembler(DynamicInstantiationResultImpl.java:106)
        at org.hibernate.sql.results.jdbc.internal.StandardJdbcValuesMapping.resolveAssemblers(StandardJdbcValuesMapping.java:53)
        at org.hibernate.sql.results.internal.ResultsHelper.createRowReader(ResultsHelper.java:78)
        at org.hibernate.sql.results.internal.ResultsHelper.createRowReader(ResultsHelper.java:64)
        at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:341)
        at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:168)
        at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:93)
        at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:31)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$0(ConcreteSqmSelectQueryPlan.java:109)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:302)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:243)
        at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:521)
        at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367)
        at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1084)
        at org.hibernate.query.Query.getResultList(Query.java:119)

我修改了查询并添加了commodityInfo

SELECT new org.kisanag.model.mandi.MarketCommodityInfo (mci AS *commodityInfo*, earth_distance(ll_to_earth(m.latitude, m.longitude), ll_to_earth(:latitude, :longitude)) / :conversion AS distance) FROM MarketCommodityInfo mci JOIN mci.id.market m JOIN mci.id.commodity c WHERE earth_distance(ll_to_earth(m.latitude, m.longitude),ll_to_earth(:latitude, :longitude)) < :within * :conversion ORDER BY distance, mci.id.arrivalDate, c.name

现在它失败了,出现以下错误

Caused by: org.hibernate.query.sqm.sql.internal.InstantiationException: Unable to determine dynamic instantiation injection strategy for org.kisanag.model.mandi.MarketCommodityInfo#commodityInfo
        at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationAssemblerInjectionImpl.lambda$new$0(DynamicInstantiationAssemblerInjectionImpl.java:82)
        at org.hibernate.internal.util.beans.BeanInfoHelper.visitBeanInfo(BeanInfoHelper.java:55)
        at org.hibernate.internal.util.beans.BeanInfoHelper.visitBeanInfo(BeanInfoHelper.java:48)
        at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationAssemblerInjectionImpl.<init>(DynamicInstantiationAssemblerInjectionImpl.java:35)
        at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationResultImpl.resolveAssembler(DynamicInstantiationResultImpl.java:208)
        at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationResultImpl.createResultAssembler(DynamicInstantiationResultImpl.java:106)
        at org.hibernate.sql.results.jdbc.internal.StandardJdbcValuesMapping.resolveAssemblers(StandardJdbcValuesMapping.java:53)
        at org.hibernate.sql.results.internal.ResultsHelper.createRowReader(ResultsHelper.java:78)
        at org.hibernate.sql.results.internal.ResultsHelper.createRowReader(ResultsHelper.java:64)
        at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:341)
        at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:168)
        at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:93)
        at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:31)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$0(ConcreteSqmSelectQueryPlan.java:109)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:302)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:243)
        at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:521)
        at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367)
        at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1084)
        at org.hibernate.query.Query.getResultList(Query.java:119)

这里是我的类MarketCommodityInfo

import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.Transient;

@Entity
public class MarketCommodityInfo {

    @EmbeddedId
    public MarketCommodityInfoKey id;

    public Double minPrice;
    public Double modalPrice;
    public Double maxPrice;
    public String unit;

    @Transient
    public Double distance;

    public MarketCommodityInfo() {
    }

    public MarketCommodityInfo(MarketCommodityInfo commodityInfo, Double distance) {
        this.id = commodityInfo.id;
        this.minPrice = commodityInfo.minPrice;
        this.modalPrice = commodityInfo.modalPrice;
        this.maxPrice = commodityInfo.maxPrice;
        this.unit = commodityInfo.unit;
        this.distance = distance;
    }
}

还有钥匙

import java.io.Serializable;
import java.util.Date;

import jakarta.persistence.Embeddable;
import jakarta.persistence.OneToOne;

@Embeddable
public class MarketCommodityInfoKey implements Serializable {

    public Date arrivalDate;

    @OneToOne
    public Commodity commodity;

    @OneToOne
    public Market market;

    public MarketCommodityInfoKey() {
    }

    public MarketCommodityInfoKey(Date arrivalDate, Commodity commodity, Market market) {
        this.arrivalDate = arrivalDate;
        this.commodity = commodity;
        this.market = market;
    }

    @Override
    public String toString() {
        return "MarketCommodityInfoKey [arrivalDate=" + arrivalDate + ", commodity=" + commodity + ", market="
                + market + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((arrivalDate == null) ? 0 : arrivalDate.hashCode());
        result = prime * result + ((commodity == null) ? 0 : commodity.hashCode());
        result = prime * result + ((market == null) ? 0 : market.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MarketCommodityInfoKey other = (MarketCommodityInfoKey) obj;
        if (arrivalDate == null) {
            if (other.arrivalDate != null)
                return false;
        } else if (!arrivalDate.equals(other.arrivalDate))
            return false;
        if (commodity == null) {
            if (other.commodity != null)
                return false;
        } else if (!commodity.equals(other.commodity))
            return false;
        if (market == null) {
            if (other.market != null)
                return false;
        } else if (!market.equals(other.market))
            return false;
        return true;
    }

}

请帮帮我

kcugc4gi

kcugc4gi1#

更新

我之前的回答是错误的。
真实的的原因是:
1.第一次尝试(使用构造函数注入)不起作用,因为Hibernate无法确定earth_distance()函数的返回类型,因为您没有将其注册为已知的SQL函数。Hibernate 6目前坚持知道所有构造函数参数的类型。
1.第二次尝试(使用字段注入)也不起作用,因为没有名为commodityInfo的字段。但是即使你修复了这个问题,它 * 仍然 * 不会工作,因为Hibernate * 仍然 * 不知道earth_distance()函数的类型。
因此,解决方案是使用FunctionContributor来注册此SQL函数及其返回类型。
现在,我怀疑DynamicInstantiationAssemblerInjectionImpl在这里有点过于繁琐,我们可以改进它以处理不是每个参数类型都已知的情况。所以我会就此开个会。

相关问题