9

I upgraded my app from spring boot 2.2.5 to 2.3.3 and I'm using spring data JPA starter with 5.4.20.Final onboard. My entites are enhanced at compile time.

Now when I'm using @EntityGraph annotation with attributePaths property over overriden findAll method from JpaRepository I'm getting this warning:

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.

Even though this warning - graph is fetched properly - I can see only one SQL query in the logs and the app behaves as before an update.

Here's my repository code:

public interface DictionaryRepository extends JpaRepository<Dictionary, Long>, QuerydslPredicateExecutor<Dictionary> {

    @EntityGraph(attributePaths = {"langs", "values", "values.langs"})
    @Override
    Page<Dictionary> findAll(Predicate predicate, Pageable pageable);
}

And here're my entities:

@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;

}

How to solve this warning? I can see that this warning is happening inside those lines of hibernate's 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 );
}
Michał Stochmal
  • 5,895
  • 4
  • 36
  • 44
  • 1
    Were you able to solve the problem in the meantime? I am currently facing the same problem and desperately looking for any hints. – Seb Aug 25 '20 at 11:37
  • 2
    Found a solution that worked for me: Add type = EntityGraph.EntityGraphType.LOAD to EntityGraph annotation in repository method. – Seb Aug 25 '20 at 12:14
  • @Seb thanks - it works in my case as well. I suppose that it's a bug in a new spring data. – Michał Stochmal Aug 25 '20 at 15:18
  • 1
    I raised my version of `spring-boot-starter-parent` from `2.2.0.RELEASE` to `2.3.2.RELEASE` and now had this issue happening to me without changing any code. following @Seb 's advice and defining `EntityGraph.EntityGraphType.LOAD` on the annotation solved it as well in my case. – kscherrer Aug 26 '20 at 09:32
  • Having this issue as well. I'd rather not change my entity graph type to load because that's not what I need, I don't want other references to default to their normal behavior. – Sebastiaan van den Broek Sep 01 '20 at 08:21
  • Can confirm. I see the same warnings in the log files after upgrading to Spring Boot 2.3.4, which pulls in Hibernate 5.4.21. – Zaki Oct 19 '20 at 10:20

1 Answers1

8

This is because of an update of hibernate to 5.4.20 in spring 2.3.3.

If you downgrade the hibernate tp 5.4.18 this problem will disappear, upgrade to 5.4.21 did not help.

In my case hibernate not just adding a warning message it actually ignores @EntityGraph(attributePaths = {...}) annotation and performs query generation according to mappings which in my case lead to a bench of N+1 problems and thousands of queries. Also, EntityGraph.EntityGraphType.LOAD does not solve the problem, as in this case hibernate will load all mappings not mentioned in @EntityGraph according to mappings fetch type which may add a lot of queries if you fatch big collections.

See details About EntityGraphType

o downgrade hibernate you can use

 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"

Here is a related issue in hibernate is https://hibernate.atlassian.net/browse/HHH-14124 it sais that the affected version 4.5.19 and fix version is 4.5.20. but still, I am getting error in spring 2.3.3(hibernate 4.5.20)

UPDATE: here is the issue posted for this bug. it is already fixed: https://hibernate.atlassian.net/browse/HHH-14212

yaroslav prokipchyn
  • 472
  • 2
  • 8
  • 17
  • 3
    Actually all my relations are specified as LAZY so using `EntityGraphType.LOAD` is not a big deal, but thanks for pointing that out. I'd rather downgrade whole spring data JPA - I wouldn't be sure that newer version of spring data won't clash with older hibernate. – Michał Stochmal Sep 07 '20 at 10:05