spring data jpa-using@entitygraph导致“指定的实体图不适用于实体”警告

xsuvu9jc  于 2021-07-12  发布在  Java
关注(0)|答案(1)|浏览(381)

我将我的应用程序从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 );
}
woobm2wo

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降级休眠您可以使用

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"

下面是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

相关问题