微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何强制 Hibernate 使用连接来获取实例的数据

如何解决如何强制 Hibernate 使用连接来获取实例的数据

我有一个使用 Hibernate 作为 JPA 提供程序的 Spring Boot 应用程序。我的应用程序有两个以 @OnetoMany / @ManyToOne 关系连接的实体。关系在两个方向都用 @Fetch(FetchMode.JOIN)fetch = FetchType.EAGER 注释。

我的实体名为 CarDriver

@Entity
@Table(name = "car")
@Data
public class Car implements Serializable,Cloneable {
   @Id
   @GenericGenerator(name = "car_seq",strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",parameters = {
   @Parameter(name = "sequence_name",value = "car_seq") })
   @GeneratedValue(generator = "car_seq")
   private Integer id;
    
   @OnetoMany(mappedBy = "car",fetch = FetchType.EAGER)
   @Fetch(FetchMode.JOIN)
   private List<Driver> drivers = new ArrayList<>();
    
   @Column(name = "license_no",nullable = false)
   private String licenseNo;
}

@Entity
@Table(name = "driver")
@Data
public class Driver implements Serializable,Cloneable {
   @Id
   @GenericGenerator(name = "driver_seq",value = "driver_seq") })
   @GeneratedValue(generator = "driver_seq")
   private Integer id;
    
   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "car_id",nullable = true)
   @Fetch(FetchMode.JOIN)
   private Car car;
    
   @Column(name = "name",nullable = false)
   private String name;
}

选择护理时(例如通过调用 Car.findById()),Hibernate 将这两个表连接在一个 sql 中,并返回一个 Car 对象,其中包含一个 Drivers 列表。>

但是如果我选择单个驱动程序,Hibernate 将加入 DriverCar 表,为我提供填充了 Driver 属性Car 对象,但它会运行第二个查询获取汽车对象列表中的所有驱动程序对象。

出于性能原因,我希望在单个查询获取所有涉及的对象,就像我获取汽车时的情况一样。但我找不到让 Hibernate 做到这一点的方法。有一个属性 hibernate.max_fetch_depth 应该这样做,但我发现它只影响取车的行为,而不影响取车时的行为。

我知道我可以使用 EntityGraph 来控制获取,并且通过使用 EntityGraph 我已经成功地检索到了一个驱动程序对象及其汽车和所有汽车的驱动程序在一个查询中。但是要做到这一点,我必须在检索对象时明确使用图形,并且在需要 Car 对象的所有各种情况下我都不能这样做。还有很多其他实体与 Car 有关系,我不想为每一个都写一个 EntityGraph

那么有没有办法告诉 Hibernate 您希望认情况下如何在实体上完成提取?我本来认为注释就足够了,但似乎必须有更多的东西,或者根本无法完成。

阿恩特

解决方法

FetchType.EAGER 是导致性能问题的最常见原因之一。你应该使用

@OneToMany(mappedBy = "car")
private List<Driver> drivers = new ArrayList<>();

并在需要时获取驱动程序

SELECT c FROM Car c JOIN FETCH c.drivers

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。