Spring 数据 JPA - 使用@EntityGraph 导致 "Entity graph specified is not applicable to the entity" 警告
Spring data JPA - using @EntityGraph causes "Entity graph specified is not applicable to the entity" warning
我将我的应用程序从 spring boot 2.2.5 升级到 2.3.3,并且我正在使用 spring 数据 JPA 启动器和 5.4.20.Final 板载。我的实体在编译时得到了增强。
现在,当我使用 @EntityGraph
注释和 attributePaths
属性 重写 JpaRepository
中的 findAll
方法时,我收到此警告:
2020-08-19 12:13:41.121 WARN 9348 --- [nio-8060-exec-3] [] [] o.h.engine.internal.TwoPhaseLoad : Entity graph specified is not applicable to the entity [DictionaryLang(id=1601, name=null, lang=null)]. Ignored.
2020-08-19 12:13:41.483 WARN 9348 --- [nio-8060-exec-3] [] [] o.h.engine.internal.TwoPhaseLoad : Entity graph specified is not applicable to the entity [DictionaryValueLang(id=3051, lang=null, name=null)]. Ignored.
尽管此警告 - 图表已正确获取 - 我只能在日志中看到一个 SQL 查询,并且应用程序的行为与更新前一样。
这是我的存储库代码:
public interface DictionaryRepository extends JpaRepository<Dictionary, Long>, QuerydslPredicateExecutor<Dictionary> {
@EntityGraph(attributePaths = {"langs", "values", "values.langs"})
@Override
Page<Dictionary> findAll(Predicate predicate, Pageable pageable);
}
这是我的实体:
@Entity
@Table(name = "DICTIONARIES")
public class Dictionary {
@Id
@SequenceGenerator(name = "SEQ_DICTIONARIES", sequenceName = "SEQ_DICTIONARIES")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DICTIONARIES")
private Long id;
@OrderBy("ordinal ASC")
@OneToMany(mappedBy = "dictionary", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<DictionaryValue> values;
@OneToMany(mappedBy = "dictionary", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<DictionaryLang> langs;
}
@Entity
@Table(name = "DICTIONARY_LANGS")
public class DictionaryLang extends BaseEntity {
@Id
@SequenceGenerator(name = "SEQ_DICTIONARY_LANGS", sequenceName = "SEQ_DICTIONARY_LANGS")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DICTIONARY_LANGS")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.PROXY)
@JoinColumn(name = "DICTIONARY_ID")
private Dictionary dictionary;
}
如何解决这个警告?我可以看到这个警告发生在休眠的 TwoPhaseLoad
class:
的那些行内
GraphImplementor fetchGraphContext = session.getFetchGraphLoadContext();
if ( fetchGraphContext != null && !fetchGraphContext.appliesTo( entity.getClass() ) ) {
LOG.warnf( "Entity graph specified is not applicable to the entity [%s]. Ignored.", entity);
fetchGraphContext = null;
session.setFetchGraphLoadContext( null );
}
这是因为在 spring 2.3.3 中将休眠更新到 5.4.20。
如果你降级hibernate tp 5.4.18这个问题就会消失,升级到5.4.21也没有帮助。
在我的例子中,hibernate 不仅添加了一条警告消息,它实际上忽略了 @EntityGraph(attributePaths = {...}) 注释并根据映射执行查询生成,在我的例子中 导致了一个长凳N+1 个问题和数千个查询。
此外,EntityGraph.EntityGraphType.LOAD 没有解决问题,因为在这种情况下,hibernate 将根据映射获取类型加载@EntityGraph 中未提及的所有映射,这可能会增加很多查询,如果你发大了 collections.
查看关于EntityGraphType
的详细信息
o 降级休眠你可以使用
implementation ("org.springframework.boot:spring-boot-starter-data-jpa") {
// to remove fibernate that came with new spring
exclude group: "org.hibernate", module: "hibernate-core"
}
// to add old hibernate
implementation "org.hibernate:hibernate-core:5.4.18.Final"
休眠中的一个相关问题是 https://hibernate.atlassian.net/browse/HHH-14124
它说受影响的版本 4.5.19 和修复版本是 4.5.20。
但是,我仍然在 spring 2.3.3(hibernate 4.5.20)
中遇到错误
更新:这是针对此错误发布的问题。它已经修复:
https://hibernate.atlassian.net/browse/HHH-14212
我将我的应用程序从 spring boot 2.2.5 升级到 2.3.3,并且我正在使用 spring 数据 JPA 启动器和 5.4.20.Final 板载。我的实体在编译时得到了增强。
现在,当我使用 @EntityGraph
注释和 attributePaths
属性 重写 JpaRepository
中的 findAll
方法时,我收到此警告:
2020-08-19 12:13:41.121 WARN 9348 --- [nio-8060-exec-3] [] [] o.h.engine.internal.TwoPhaseLoad : Entity graph specified is not applicable to the entity [DictionaryLang(id=1601, name=null, lang=null)]. Ignored.
2020-08-19 12:13:41.483 WARN 9348 --- [nio-8060-exec-3] [] [] o.h.engine.internal.TwoPhaseLoad : Entity graph specified is not applicable to the entity [DictionaryValueLang(id=3051, lang=null, name=null)]. Ignored.
尽管此警告 - 图表已正确获取 - 我只能在日志中看到一个 SQL 查询,并且应用程序的行为与更新前一样。
这是我的存储库代码:
public interface DictionaryRepository extends JpaRepository<Dictionary, Long>, QuerydslPredicateExecutor<Dictionary> {
@EntityGraph(attributePaths = {"langs", "values", "values.langs"})
@Override
Page<Dictionary> findAll(Predicate predicate, Pageable pageable);
}
这是我的实体:
@Entity
@Table(name = "DICTIONARIES")
public class Dictionary {
@Id
@SequenceGenerator(name = "SEQ_DICTIONARIES", sequenceName = "SEQ_DICTIONARIES")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DICTIONARIES")
private Long id;
@OrderBy("ordinal ASC")
@OneToMany(mappedBy = "dictionary", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<DictionaryValue> values;
@OneToMany(mappedBy = "dictionary", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<DictionaryLang> langs;
}
@Entity
@Table(name = "DICTIONARY_LANGS")
public class DictionaryLang extends BaseEntity {
@Id
@SequenceGenerator(name = "SEQ_DICTIONARY_LANGS", sequenceName = "SEQ_DICTIONARY_LANGS")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DICTIONARY_LANGS")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.PROXY)
@JoinColumn(name = "DICTIONARY_ID")
private Dictionary dictionary;
}
如何解决这个警告?我可以看到这个警告发生在休眠的 TwoPhaseLoad
class:
GraphImplementor fetchGraphContext = session.getFetchGraphLoadContext();
if ( fetchGraphContext != null && !fetchGraphContext.appliesTo( entity.getClass() ) ) {
LOG.warnf( "Entity graph specified is not applicable to the entity [%s]. Ignored.", entity);
fetchGraphContext = null;
session.setFetchGraphLoadContext( null );
}
这是因为在 spring 2.3.3 中将休眠更新到 5.4.20。
如果你降级hibernate tp 5.4.18这个问题就会消失,升级到5.4.21也没有帮助。
在我的例子中,hibernate 不仅添加了一条警告消息,它实际上忽略了 @EntityGraph(attributePaths = {...}) 注释并根据映射执行查询生成,在我的例子中 导致了一个长凳N+1 个问题和数千个查询。 此外,EntityGraph.EntityGraphType.LOAD 没有解决问题,因为在这种情况下,hibernate 将根据映射获取类型加载@EntityGraph 中未提及的所有映射,这可能会增加很多查询,如果你发大了 collections.
查看关于EntityGraphType
的详细信息o 降级休眠你可以使用
implementation ("org.springframework.boot:spring-boot-starter-data-jpa") {
// to remove fibernate that came with new spring
exclude group: "org.hibernate", module: "hibernate-core"
}
// to add old hibernate
implementation "org.hibernate:hibernate-core:5.4.18.Final"
休眠中的一个相关问题是 https://hibernate.atlassian.net/browse/HHH-14124 它说受影响的版本 4.5.19 和修复版本是 4.5.20。 但是,我仍然在 spring 2.3.3(hibernate 4.5.20)
中遇到错误更新:这是针对此错误发布的问题。它已经修复: https://hibernate.atlassian.net/browse/HHH-14212