gpt4 book ai didi

java - hibernate条件查询创建多个sql

转载 作者:行者123 更新时间:2023-11-29 19:32:07 29 4
gpt4 key购买 nike

我在应用程序中遇到了一个非常奇怪的 hibernate 标准问题。下面在我的源代码片段中提到。

实体类

    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 方法,以使用未急切加入的关联的属性,并强制 hibernate 进行代理,从而在事务内获取已卸载的实体。

关于java - hibernate条件查询创建多个sql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41726015/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com