繁体   English   中英

休眠条件查询创建多个SQL

[英]hibernate criteria query creating multiple sql

我的应用程序中的休眠标准面临一个非常奇怪的问题。 下面是我的源代码片段中提到的内容。

实体类别

    import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Table(name = "AIRPORT")
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Airport implements Serializable {

    private static final long serialVersionUID = -7120581694566566178L;
    private Long id;
    private String countryCode;
    private String countryName;
    private String cityCode;
    private String cityName;
    private String airportCode;
    private String airportName;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "COUNTRY_NAME")
    public String getCountryName() {
        return countryName;
    }

    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }

    @Column(name = "COUNTRY_CODE", length = 10)
    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }

    @Column(name = "CITY_CODE", length = 25)
    public String getCityCode() {
        return cityCode;
    }

    public void setCityCode(String cityCode) {
        this.cityCode = cityCode;
    }

    @Column(name = "CITY_NAME")
    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    @Column(name = "AIRPORT_CODE", unique = true, length = 10)
    public String getAirportCode() {
        return airportCode;
    }

    public void setAirportCode(String airportCode) {
        this.airportCode = airportCode;
    }

    @Column(name = "AIRPORT_NAME")
    public String getAirportName() {
        return airportName;
    }

    public void setAirportName(String airportName) {
        this.airportName = airportName;
    }
}

DAO类

    Criteria criteria = getSession().createCriteria(getTemplateClass());
    criteria.addOrder(Order.asc("countryCode"));
    criteria.addOrder(Order.asc("cityCode"));
    criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    criteria.setCacheable(true);
    return (List<Airport>) criteria.list();

启动应用程序并查询结果时生成的SQL

Hibernate: select this_.ID as ID1_12_0_, this_.AIRPORT_CODE as AIRPORT_2_12_0_, this_.AIRPORT_NAME as AIRPORT_3_12_0_, this_.CITY_CODE as CITY_COD4_12_0_, this_.CITY_NAME as CITY_NAM5_12_0_, this_.COUNTRY_CODE as COUNTRY_6_12_0_, this_.COUNTRY_NAME as COUNTRY_7_12_0_ from AIRPORT this_ order by this_.COUNTRY_CODE asc, this_.CITY_CODE asc

如果我再次调用相同的代码并假设我有1000个机场列表,则它将在查询下面执行1000次。 这种行为很奇怪。

Hibernate: select airport0_.ID as ID1_12_0_, airport0_.AIRPORT_CODE as AIRPORT_2_12_0_, airport0_.AIRPORT_NAME as AIRPORT_3_12_0_, airport0_.CITY_CODE as CITY_COD4_12_0_, airport0_.CITY_NAME as CITY_NAM5_12_0_, airport0_.COUNTRY_CODE as COUNTRY_6_12_0_, airport0_.COUNTRY_NAME as COUNTRY_7_12_0_ from AIRPORT airport0_ where airport0_.ID=?
Hibernate: select airport0_.ID as ID1_12_0_, airport0_.AIRPORT_CODE as AIRPORT_2_12_0_, airport0_.AIRPORT_NAME as AIRPORT_3_12_0_, airport0_.CITY_CODE as CITY_COD4_12_0_, airport0_.CITY_NAME as CITY_NAM5_12_0_, airport0_.COUNTRY_CODE as COUNTRY_6_12_0_, airport0_.COUNTRY_NAME as COUNTRY_7_12_0_ from AIRPORT airport0_ where airport0_.ID=?
Hibernate: select airport0_.ID as ID1_12_0_, airport0_.AIRPORT_CODE as AIRPORT_2_12_0_, airport0_.AIRPORT_NAME as AIRPORT_3_12_0_, airport0_.CITY_CODE as CITY_COD4_12_0_, airport0_.CITY_NAME as CITY_NAM5_12_0_, airport0_.COUNTRY_CODE as COUNTRY_6_12_0_, airport0_.COUNTRY_NAME as COUNTRY_7_12_0_ from AIRPORT airport0_ where airport0_.ID=?
........
........

即使我在使用ehcache,甚至在我的标准中使用以下行。

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

任何帮助将不胜感激。

我可以想到几种可能的原因:

  1. 您的实体中定义了一个关联,默认情况下该关联被配置为渴望加入,并且您还指定了该关联使用FetchMode.SELECT (这称为N + 1问题)

  2. 在事务仍处于打开状态时,您正在与每个被设置为延迟加载的Airport对象的关联进行交互。 我的意思是,通过交互,您正在使用getter访问关系,从而迫使Hibernate取消关联实体的代理。 由于在事务仍处于打开状态且尚未加载关联实体的情况下发生了取消代理,因此Hibernate会自动为您获取关联。

  3. 您已经编写了Airport实体的哈希码或equals方法,以使用关联的属性,该属性没有急切地加入,并会强制休眠状态进行代理,从而在事务内获取未加载的实体。

暂无
暂无

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

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