如何解决Spring数据JPA-使用@EntityGraph会导致“指定的实体图不适用于该实体”警告
我将我的应用程序从Spring Boot 2.2.5升级到了2.3.3,我使用的Spring Data JPA入门版软件是5.4.20.Final。在编译时,我的实体得到了增强。
现在,当我在@EntityGraph
的覆盖attributePaths
方法上使用具有findAll
属性的JpaRepository
注解时,我得到以下警告:
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",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
类的那些行中发生:
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 );
}
解决方法
这是因为在春季2.3.3中将休眠模式更新为5.4.20。
如果您将休眠tp 5.4.18降级,此问题将消失,升级到5.4.21并没有帮助。
在我的情况下,hibernate不仅添加警告消息,它实际上忽略了@EntityGraph(attributePaths = {...})批注并根据映射执行查询生成,在我的情况下,此映射导致N + 1基准问题和成千上万的查询。 另外, EntityGraph.EntityGraphType.LOAD不能解决问题,因为在这种情况下,hibernate将根据映射获取类型加载@EntityGraph中未提及的所有映射,这可能会增加很多查询集合。
查看有关EntityGraphType
的详细信息降级可以使用的休眠状态
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。 但仍然在春季2.3.3(休眠4.5.20)中出现错误
更新:这是此错误的发布问题。它已经修复: https://hibernate.atlassian.net/browse/HHH-14212
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。