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 );
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With