gpt4 book ai didi

java - 当 JOIN FETCH 与主 ID 以外的引用列一起使用时,Hibernate 执行多个查询

转载 作者:行者123 更新时间:2023-12-05 07:07:10 25 4
gpt4 key购买 nike

我有以下问题。

每当使用 JOIN FETCH 子句通过查询调用我的存储库时,Hibernate 都会生成一个根本不需要的额外查询。这里的主要问题是,通过相应的数据库结构,两个实体(对应于两个单独的表)应该由一个不同列连接,而不是两个实体的ID(即“customerid"在实体 Order 中由 @JoinColumn(name = "customerid", referencedColumnName = "customerid")"表示。

存储库如下:

public interface CustomerRepository extends CrudRepository<Customer, Long>{

Customer findByMsisdn(String msisdn);

@Query("SELECT c FROM Customer c JOIN FETCH c.orders WHERE c.msisdn =:msisdn")
Customer getCustomersAndOrdersByMsisdn(@Param("msisdn") String msisdn);
}

每当我调用 getCustomersAndOrdersByMsisdn 方法时,都会生成以下两个查询(自然地,我们希望只生成查询 1):

--Query1
select
customer0_.id as id1_0_0_,
orders1_.id as id1_1_1_,
customer0_.customerid as customer2_0_0_,
customer0_.msisdn as msisdn3_0_0_,
customer0_.status as status4_0_0_,
orders1_.customerid as customer4_1_1_,
orders1_.orderid as orderid2_1_1_,
orders1_.orderstatus as ordersta3_1_1_,
orders1_.customerid as customer4_1_0__,
orders1_.id as id1_1_0__
from
customers customer0_
inner join
orders orders1_
on customer0_.customerid = orders1_.customerid
where
customer0_.msisdn =?

--Query2
select
customer0_.id as id1_0_0_,
customer0_.customerid as customer2_0_0_,
customer0_.msisdn as msisdn3_0_0_,
customer0_.status as status4_0_0_
from
customers customer0_
where
customer0_.customerid =?

我的两个实体(为清楚起见,我在这里省略了 getter 和 setter,它们当然存在于我的代码中)是:

@Entity
@Table(name = "customers")
public class Customer implements Serializable {
static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;


@Column(name = "msisdn")
private String msisdn;

@Column(name = "status")
private String status;

@Column(name = "customerid", unique = true)
@NaturalId
private String customerid;

@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private Set<Order> orders;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id &&
msisdn.equals(customer.msisdn) &&
customerid.equals(customer.customerid);
}

@Override
public int hashCode() {
return Objects.hash(id, msisdn, customerid);
}
}

@Entity
@Table(name = "orders")
public class Order implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column(name = "orderid")
private int orderid;

@Column(name = "orderstatus")
private String orderstatus;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "customerid", referencedColumnName = "customerid")
private Customer customer;


@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Order orders = (Order) o;
return id == orders.id &&
orderid == orders.orderid;
}

@Override
public int hashCode() {
return Objects.hash(id, orderid);
}
}

最佳答案

这是绝对正常的,它的发生是因为连接是使用自然 ID 而不是实体的 ID 进行的。 Hibernate 使用实体的 id 而不是定义的自然 id 来对实体执行操作。

因此在进行连接时,hibernate 需要获取具有自然 id 的客户的实体。

有关详细信息,请阅读文章 @NaturalId – A good way to persist natural IDs with Hibernate?

关于java - 当 JOIN FETCH 与主 ID 以外的引用列一起使用时,Hibernate 执行多个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62281835/

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