我将我的应用程序从springboot2.2.5升级到了2.3.3,并且我正在使用springdatajpastarter和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", 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;
}
如何解决此警告?我可以看到这个警告发生在hibernate的 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 );
}
1条答案
按热度按时间woobm2wo1#
这是因为在Spring2.3.3中将hibernate更新为5.4.20。
如果你把hibernate的tp5.4.18降级,这个问题就会消失,升级到5.4.21没有帮助。
在我的例子中,hibernate不只是添加一条警告消息,它实际上忽略了@entitygraph(attributepaths={…})注解,并根据Map执行查询生成,这在我的例子中会导致n+1问题和数千个查询。另外,entitygraph.entitygraphtype.load并不能解决这个问题,因为在本例中,hibernate将根据mappings fetch type加载@entitygraph中未提及的所有Map,如果您获取大集合,则可能会添加大量查询。
请参阅entitygraphtype的详细信息
o降级休眠您可以使用
下面是hibernate中的一个相关问题https://hibernate.atlassian.net/browse/hhh-14124 据说受影响的版本是4.5.19,修复版本是4.5.20。但是,我仍然在Spring2.3.3(Hibernate4.5.20)中遇到了错误
更新:这里是这个错误发布的问题。已修复:https://hibernate.atlassian.net/browse/hhh-14212