相关疑难解决方法(0)

为什么我不会在每个延迟加载的关系中使用@BatchSize?

hibernate的@BatchSize注释允许批量提取延迟加载的实体.例如,如果我有类似的东西:

public class Product {


    @OneToMany(fetchType=LAZY)
    @BatchSize(size=10)
    private ProductCategory category;

}
Run Code Online (Sandbox Code Playgroud)

现在,如果我得到产品的类别,Hibernate将获取最多十个产品的类别,这些产品在当前会话中并且尚未初始化其类别字段.这样可以节省大量SQL调用数据库.到现在为止还挺好.现在我想知道为什么我不会在每个懒惰的加载关系上使用@BatchSize注释?毕竟为什么我想要额外调用数据库?显然必须有这样的原因,否则Hibernate的人可能会把它作为默认,但我目前看不到它.

java performance hibernate

12
推荐指数
2
解决办法
8337
查看次数

获取多个onetoMany关系Hibernate JPA

我正在使用Hibernate JPA 1.0.

我有以下类型的模型,我认为很多ToOne和oneToOne关系"热切地"获取并且oneToMany"懒洋洋地"获取.

我想获取实体A及其所有关联,其中a.id =?

  • OneToMany B
    • B oneToOne C.
      • C oneToMany D
    • B oneToOne E.
      • E oneToMany D
    • B oneToOne F.
      • F oneToMany D

是否可以在单个查询中加载此实体?或者在一系列查询中记住"n + 1选择问题"!

到目前为止,我加载所有A关联的解决方案是执行以下操作:

"从A JOIN FETCH中选择DISTINCT a a.bs WHERE a.id =:aID"

然后使用代码进行迭代以获取所有其他关联.

集合B bs = A.getBs();

         for (final B b : bs) {
         b.getCs().getDs().size();
         b.getEs().getDs().size();
         b.getFs().getDs().size();
         }
Run Code Online (Sandbox Code Playgroud)

显然必须有更好的方法来做到这一点.

java orm hibernate jpa

7
推荐指数
2
解决办法
8429
查看次数

Hibernate的批量获取算法如何工作?

我在"Manning-Java Persistence with Hibernate"中找到了批量获取算法的描述:

什么是真正的批量获取算法?(...)想象一下,批量大小为20,总共有119个未初始化的代理需要批量加载.在启动时,Hibernate读取映射元数据并在内部创建11个批处理加载器.每个加载器知道它可以初始化多少代理:20,10,9,8,7,6,5,4,3,2,1.目标是最小化加载器创建的内存消耗并创建足够的每个加载器可以生成可能的批量提取.另一个目标是显着减少SQL SELECT的数量.要初始化119个代理,Hibernate会执行7个批处理(你可能预计会有6个,因为6 x 20> 119).应用的批处理加载程序是Hibernate自动选择的五倍20倍,一倍10倍和一倍9倍.

但我仍然不明白它是如何工作的.

  1. 为什么11批装载机?
  2. 为什么批量加载器可以初始化:20,10,9,8,7,6,5,4,3,2,1代理?

如果有人可以提出一步一步的算法...... :)

java algorithm optimization fetching-strategy java-ee

7
推荐指数
2
解决办法
1775
查看次数

Hibernate:复杂对象的初始化

我在合理的时间内使用DB完全加载非常复杂的对象并且查询数量合理.

我的对象有很多嵌入式实体,每个实体都引用另一个实体,另一个实体引用另一个实体等等(所以,嵌套级别为6)

所以,我已经创建了一个示例来演示我想要的内容:https: //github.com/gladorange/hibernate-lazy-loading

我有用户.

用户拥有@OneToMany最喜欢的橘子,苹果,葡萄藤和桃子的集合.每个Grapevine都有@OneToMany葡萄收藏.每个水果都是另一个只有一个String字段的实体.

我正在创造用户,每种类型有30种最喜欢的水果,每种葡萄都有10种葡萄.所以,我在DB中有421个实体--30*4个水果,100*30个葡萄和一个用户.

我想要的是:我想使用不超过6个SQL查询加载它们.并且每个查询不应该产生大的结果集(对于该示例,大的结果集具有超过200个记录).

我理想的解决方案如下:

  • 6个要求.第一个请求返回有关用户的信息,结果集的大小为1.

  • 关于该用户的苹果的第二个请求返回信息和结果集的大小是30.

  • 第三,第四和第五个请求返回相同,第二个(结果集大小= 30),但对于Grapevines,Oranges和Peaches.

  • 第六个请求返回所有葡萄藤的葡萄

这在SQL世界中非常简单,但我无法用JPA(Hibernate)实现这一点.

我尝试了以下方法:

  1. 使用fetch join,就像from User u join fetch u.oranges ....这太糟糕了.结果集为30*30*30*30,执行时间为10秒.请求数量= 3.我尝试没有葡萄,葡萄你会得到x10大小的结果集.

  2. 只需使用延迟加载.这是此示例中的最佳结果(对于葡萄,@ Fetch = SUBSELECT).但在这种情况下,我需要手动迭代每个元素集合.此外,subselect fetch太全局设置,所以我想有一些可以在查询级别工作的东西.结果集和时间接近理想.6个查询和43毫秒.

  3. 加载实体图.与获取连接相同,但它也要求每种葡萄都能获得葡萄藤.但是,结果时间更好(6秒),但仍然很糟糕.请求数> 30.

  4. 我试图在单独的查询中用"手动"加载实体来欺骗JPA.喜欢:

    SELECT u FROM User where id=1;
    SELECT a FROM Apple where a.user_id=1;
    

延迟加载有点糟糕,因为每个集合需要两个查询:第一个查询到手动加载实体(我完全控制这个查询,包括加载相关实体),第二个查询延迟加载相同的实体由Hibernate本身(这是由Hibernate自动执行)

执行时间为52,查询数量= 10(用户为1,葡萄为1,每个水果收集为4*2)

实际上,结合SUBSELECT fetch的"手动"解决方案允许我使用"简单"的获取连接来在一个查询中加载必要的实体(比如@OneToOne实体)所以我将使用它.但我不喜欢我必须执行两个查询来加载集合.

有什么建议?

java optimization hibernate jpa

7
推荐指数
2
解决办法
1137
查看次数

Infinispan JPA二级缓存默认值

我正在尝试将Infinispan配置为hibernate二级缓存.一切都很好,但我想调整默认配置,即所有缓存共享的值.

缓存是用于注明实体自动创建的@Cache,我可以通过一个在对其进行自定义一个infinispan.xml通过<distributed-cache-configuratoin>.但是,我希望所有这些缓存都有默认值(例如驱逐策略).

另一件事是,我想将所有这些生成的缓存标记为"分布式"(默认情况下它们是"本地").

这是我的一个例外infinispan.xml:

<cache-container default-cache="default" statistics="true">
    <transport stack="external-file" />
    <!-- Configuring specifics for the User entity. How to do it globally? -->
    <distributed-cache-configuration name="user" statistics="true" />
</cache-container>
Run Code Online (Sandbox Code Playgroud)

我该怎么做这些事情?

java hibernate jpa second-level-cache infinispan

5
推荐指数
1
解决办法
1613
查看次数