我将我的应用程序从spring boot 2.2.5升级到2.3.3,并且我正在使用spring data JPA starter和5.4.20.Final板载。我的实体在编译时得到了增强。
现在,当我使用@EntityGraph
注释与属性路径
属性覆盖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的<code>TwoPhaseLoad</code>类的那些行中:
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 );
}
这是因为在Spring 2.3.3中将hibernate更新到5.4.20。
如果你降级Hibernatetp 5.4.18这个问题将消失,升级到5.4.21没有帮助。
在我的例子中,hibernate不只是添加了一个警告消息,它实际上忽略了@EntityGraph(attributePaths = {...})注释,并根据映射执行查询生成,在我的例子中,这会导致N-1个问题和数千个查询。还有,EntityGraph。LOAD并不能解决问题,因为在这种情况下,hibernate将根据mappings fetch类型加载@EntityGraph中没有提到的所有映射,如果您查找大的集合,这可能会增加很多查询。
查看有关EntityGraphType的详细信息
o降级Hibernate,您可以使用
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。但是,我仍然在spring 2.3.3(hibernate 4.5.20)中遇到错误
更新:以下是针对此错误发布的问题。它已经固定:https://hibernate.atlassian.net/browse/HHH-14212
当应用程序基于Spring Boot时,不考虑定义的实体图。相反,在JUnit测试期间,一切正常。 领域非常简单:书籍及其类别(多对多关系) 图书类: 类别类: 带有使用创建的实体图的方法的JPA存储库: REST控制器中的用法: 启动Spring Boot(mvn Spring Boot:run)并导航到http://localhost:8080/books书籍会被显示,但它们有各自的类别(由于
我用Spring和Hibernate开发了我的Java应用程序,我有两个实体。 我创建我的服务类别,以获得Hibernate的结果 当我调试时,我在这一行中得到这个错误: 104165[http-bio-8080-exec-3]警告组织。冬眠util。JDBCExceptionReporter-SQL错误:904,SQLState:42000 104166[http-bio-8080-exec-3
我在各自的字段中使用了@CreatedBy、@CreatedDate、@LastModifiedBy和@LastModifiedDate注释。通过使用@MappdSuperclass、@EntityListeners,我能够持久化上面的列。 但这不适用于以下情况: 审计员我mpl.java JpaAuditConfiguration。Java语言 在这种情况下,实体B填充了审计列。但实体A并非如此
这个问题几乎说明了一切。使用JPARepository,我如何更新一个实体? JPARepository只有一个save方法,它并不告诉我它实际上是create还是update。例如,我向数据库用户插入一个简单的对象,它有三个字段:、和: 然后我只需调用,此时它实际上是对数据库的插入: 到目前为止还不错。现在我想更新这个用户,比如说改变他的年龄。为此,我可以使用查询,无论是QueryDSL还是Na
另外,当切换到一个新的视图(spring controller中的新调用)时,来自上一个视图的事务将已经关闭,我必须进行新的调用,以与用户有不同的数据。我不明白如果您不在相同的事务服务方法中,fetch lazy有什么帮助,除非我没有遗漏什么。 例如,如果我需要“orderwiew.html”中的订单数据,惰性加载订单是没有帮助的,我必须对相同的用户数据和额外的订单数据进行另一次完整调用
我有几个实体,并使用Spring Data JPA存储库与规范查询我的数据库。因此,我创建了一个泛型类< code>SpecBuilder来基于查询描述(< code>MyQueryDescriptor)构建我的查询。 我的存储库: 和 现在有三件事我不太确定:< br> 1) 使用泛型SpecBuilder是一个干净的设计吗? 2) 有没有办法避免为每个实体编写这些存储库接口?假设一个通用存储库