Java 什么';这就是@Fetch(FetchMode.JOIN)和joinfetch之间的区别
今天我面临重复查询问题(N+1选择)。 我的问题是Java 什么';这就是@Fetch(FetchMode.JOIN)和joinfetch之间的区别,java,hibernate,jpa,Java,Hibernate,Jpa,今天我面临重复查询问题(N+1选择)。 我的问题是注释和JQL命令 JOIN-FETCH 对我来说,注释没有任何区别 记下我收到的结果。谁能向我解释一下吗 这是我的班级: @Entity @Table(name = "tab_resp") public class Responsavel implements Serializable, IBeanEnable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
注释
和JQL命令
JOIN-FETCH
对我来说,注释没有任何区别
记下我收到的结果。谁能向我解释一下吗
这是我的班级:
@Entity
@Table(name = "tab_resp")
public class Responsavel implements Serializable, IBeanEnable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@GenField(fieldText = "Nome", columnName = "Nome", type = GenField.CHAR_STRING, isRepresentation = true)
@Column(length = 70)
private String nome;
@GenField(fieldText = "Email", columnName = "Email", type = GenField.CHAR_STRING)
@Column(length = 150)
private String email;
@GenField(fieldText = "Empresa", columnName = "Empresa", type = GenField.OBJECT)
@OneToOne//(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private Empresa empresa;
@GenField(fieldText = "Cargo", columnName = "Cargo", type = GenField.OBJECT)
@OneToOne//(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private Cargo cargo;
@GenField(fieldText = "Data Cadastro", columnName = "Data Cadastro", type = GenField.DATE, dateTimeFormat = "dd/MM/yyyyy HH:mm:ss")
@Column(name = "dh_cad")
private LocalDateTime dataHoraRegistro;
@GenField(fieldText = "Data Atualização", columnName = "Data Atualização", type = GenField.DATE, dateTimeFormat = "dd/MM/yyyyy HH:mm:ss")
@Column(name = "dh_atu")
private LocalDateTime dataHoraAtualizacao;
@GenField(fieldText = "Ativo", columnName = "Ativo", type = GenField.BOOLEAN)
@Convert(converter = BooleanToIntegerConverter.class)
private Boolean ativo;
...
结果:
Hibernate: select responsave0_.id as id1_18_, responsave0_.ativo as ativo2_18_, responsave0_.cargo_id as cargo_id7_18_, responsave0_.dh_atu as dh_atu3_18_, responsave0_.dh_cad as dh_cad4_18_, responsave0_.email as email5_18_, responsave0_.empresa_id as empresa_8_18_, responsave0_.nome as nome6_18_ from tab_resp responsave0_
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select empresa0_.id as id1_10_0_, empresa0_.ativo as ativo2_10_0_, empresa0_.dh_atu as dh_atu3_10_0_, empresa0_.dh_cad as dh_cad4_10_0_, empresa0_.nome as nome5_10_0_ from tab_empr empresa0_ where empresa0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select empresa0_.id as id1_10_0_, empresa0_.ativo as ativo2_10_0_, empresa0_.dh_atu as dh_atu3_10_0_, empresa0_.dh_cad as dh_cad4_10_0_, empresa0_.nome as nome5_10_0_ from tab_empr empresa0_ where empresa0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select responsave0_.id as id1_18_0_, cargo1_.id as id1_5_1_, empresa2_.id as id1_10_2_, responsave0_.ativo as ativo2_18_0_, responsave0_.cargo_id as cargo_id7_18_0_, responsave0_.dh_atu as dh_atu3_18_0_, responsave0_.dh_cad as dh_cad4_18_0_, responsave0_.email as email5_18_0_, responsave0_.empresa_id as empresa_8_18_0_, responsave0_.nome as nome6_18_0_, cargo1_.ativo as ativo2_5_1_, cargo1_.dataHoraRegistro as dataHora3_5_1_, cargo1_.descricao as descrica4_5_1_, empresa2_.ativo as ativo2_10_2_, empresa2_.dh_atu as dh_atu3_10_2_, empresa2_.dh_cad as dh_cad4_10_2_, empresa2_.nome as nome5_10_2_ from tab_resp responsave0_ inner join tab_carg cargo1_ on responsave0_.cargo_id=cargo1_.id inner join tab_empr empresa2_ on responsave0_.empresa_id=empresa2_.id
带有Fecth选项的JQL只产生一个查询命令
dao.consulta("select r from Responsavel r JOIN FETCH r.cargo c JOIN FETCH r.empresa e");
结果:
Hibernate: select responsave0_.id as id1_18_, responsave0_.ativo as ativo2_18_, responsave0_.cargo_id as cargo_id7_18_, responsave0_.dh_atu as dh_atu3_18_, responsave0_.dh_cad as dh_cad4_18_, responsave0_.email as email5_18_, responsave0_.empresa_id as empresa_8_18_, responsave0_.nome as nome6_18_ from tab_resp responsave0_
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select empresa0_.id as id1_10_0_, empresa0_.ativo as ativo2_10_0_, empresa0_.dh_atu as dh_atu3_10_0_, empresa0_.dh_cad as dh_cad4_10_0_, empresa0_.nome as nome5_10_0_ from tab_empr empresa0_ where empresa0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select empresa0_.id as id1_10_0_, empresa0_.ativo as ativo2_10_0_, empresa0_.dh_atu as dh_atu3_10_0_, empresa0_.dh_cad as dh_cad4_10_0_, empresa0_.nome as nome5_10_0_ from tab_empr empresa0_ where empresa0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select cargo0_.id as id1_5_0_, cargo0_.ativo as ativo2_5_0_, cargo0_.dataHoraRegistro as dataHora3_5_0_, cargo0_.descricao as descrica4_5_0_ from tab_carg cargo0_ where cargo0_.id=?
Hibernate: select responsave0_.id as id1_18_0_, cargo1_.id as id1_5_1_, empresa2_.id as id1_10_2_, responsave0_.ativo as ativo2_18_0_, responsave0_.cargo_id as cargo_id7_18_0_, responsave0_.dh_atu as dh_atu3_18_0_, responsave0_.dh_cad as dh_cad4_18_0_, responsave0_.email as email5_18_0_, responsave0_.empresa_id as empresa_8_18_0_, responsave0_.nome as nome6_18_0_, cargo1_.ativo as ativo2_5_1_, cargo1_.dataHoraRegistro as dataHora3_5_1_, cargo1_.descricao as descrica4_5_1_, empresa2_.ativo as ativo2_10_2_, empresa2_.dh_atu as dh_atu3_10_2_, empresa2_.dh_cad as dh_cad4_10_2_, empresa2_.nome as nome5_10_2_ from tab_resp responsave0_ inner join tab_carg cargo1_ on responsave0_.cargo_id=cargo1_.id inner join tab_empr empresa2_ on responsave0_.empresa_id=empresa2_.id
我刚刚测试了你的代码,它工作正常。哪个版本的Hibernate?您是否确实加载了带有注释掉的
(fetch=FetchType.EAGER)
的实体@Fetch(FetchMode.JOIN)
和(Fetch=FetchType.EAGER)
实际上是相互排斥的。当我使用FetchType.LAZY或FetchType.EAGER时,我运行了一些测试,将(fetch=FetchType.LAZY)和查询的数量减少。有什么规则可以帮助我选择更好的吗?当我定义FetchType.LAZY时,加载相关实体的更好方法是什么?请参阅和。默认情况下,“对一”关系是急切地获取的,而“对多”关系是惰性地获取的,这对于大多数应用程序来说是合理的。只有当“到多”关系实际上是“到少”的关联时,您才应该急切地加载“到多”关系,并且如果没有相关的子实体(例如,Order
和LineItem
s),则父实体也不太有用,同时使用FetchType.LAZY
,指定@Fetch
没有意义:因为您不希望加入Fetch
,所以在您请求之前不会加载关联的实体,此时显然将使用单个查询完成加载