Java JPA存储库阅读速度慢

Java JPA存储库阅读速度慢,java,sql-server,hibernate,spring-data-jpa,Java,Sql Server,Hibernate,Spring Data Jpa,我有一个具有相当大实体模型的数据库。 总共有14个表,平均约有10万条记录 当我测试从数据库中获取一个实体并将其转换为json并将其返回给调用方的应用程序时,需要7秒钟才能获得条目 这似乎不是一个初始化问题,因为如果我连续两次调用同一个调用,它们都需要大约10秒来获取数据 当我启用sql脚本日志记录时,我发现对于每次读取的实体,hibernate都会向数据库发送数百个sql请求。 (实际数量基于实体拥有多少连接/许可证/产品/服务等,但对于我的测试条目,我得到了286个查询(总共花了大约7秒))

我有一个具有相当大实体模型的数据库。 总共有14个表,平均约有10万条记录

当我测试从数据库中获取一个实体并将其转换为json并将其返回给调用方的应用程序时,需要7秒钟才能获得条目

这似乎不是一个初始化问题,因为如果我连续两次调用同一个调用,它们都需要大约10秒来获取数据

当我启用sql脚本日志记录时,我发现对于每次读取的实体,hibernate都会向数据库发送数百个sql请求。 (实际数量基于实体拥有多少连接/许可证/产品/服务等,但对于我的测试条目,我得到了286个查询(总共花了大约7秒)) 当数据库为空(测试应返回的数据除外)时,大约需要6秒

我想问题是因为我将@OneToMany's和@ManyToMany's fetch设置为Lazy,但是当我将它们设置为eager时,我得到了多个fetch包的错误

@javax.persistence.OneToMany(fetch = javax.persistence.FetchType.LAZY)
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.FALSE)
@javax.persistence.JoinColumn(name = "ProductId")
这是我拥有的OneToMany关系的一个示例,它模拟了无多个获取包错误的急切获取

这是一个普遍的问题吗?
如何提高读取速度?

Hibernate不允许将多个类型列表集合标记为“急切”

加载数据的最佳方法是使用联接获取

select e from YourEntity JOIN FETCH e.yourList l
另一种选择是使用EntityGraph来定义即时加载

请在此处阅读有关该主题的更多信息:

如果使用Spring数据JPA存储库接口,则可以使用NamedEntityGraphs:


您的JSON文档有多大,有多少关系?Fetch类型通常应该是惰性的,但是如果您需要读取世界,那么它总是很慢的。如果空表中的单个实体需要6秒钟,那么它一定是巨大的!生成的json由数据库中总共502条记录组成,长度为2652行。如果删除Hibernate特定的LazyCollection注释,您将获得与portable FetchType.EAGER相同的效果(我一般不建议这样做)。然后看看有多少查询?您是进行了502次选择,还是有一些选择会产生很多结果?如果我将fetch type设置为Earge,我会得到一个MultipleBagFetchException,LazyCollection注释是解决此问题的方法,我不确定还有哪些其他方法我不想使用Earge fetching,我建议根据下面的答案使用连接获取或获取图,或者更改批大小以进行读取。然而,为了达到这一目的,我想知道当系统使用延迟抓取时有多少个选择,以及有多少个表?虽然我没有使用JPQL查询,但我使用的是org.springframework.data.jpa.repository.JpaRepository,它根据接口的方法名称进行查询。我更喜欢使用存储库方法,因为用它模拟数据库是多么容易,因此我建议使用EntityGraphs。查看我的更新答案。据我所知,它只会将查询较早地拉入流程,但不会减少完成的查询数量。您遇到了经典的n+1读取问题。有几种方法可以解决这个问题: