Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 加载Hibernate实体时如何优化Carstesian产品_Java_Hibernate_Jpa_Spring Data - Fatal编程技术网

Java 加载Hibernate实体时如何优化Carstesian产品

Java 加载Hibernate实体时如何优化Carstesian产品,java,hibernate,jpa,spring-data,Java,Hibernate,Jpa,Spring Data,为了演示我的问题,我创建了一个简单的Spring引导应用程序。它有一个实体,具有ID、两个字符串属性和两个集合 我跟踪了Hibernate,发现Cat是通过这个SQL从DB加载的 select cat0_.id as id1_0_0_, cat0_.name as name2_0_0_, cat0_.sex as sex3_0_0_, colors1_.cat_id as cat_id1_1_1_, colors1_.color as color2_1_1_,

为了演示我的问题,我创建了一个简单的Spring引导应用程序。它有一个实体,具有ID、两个字符串属性和两个集合

我跟踪了Hibernate,发现Cat是通过这个SQL从DB加载的

select cat0_.id as id1_0_0_, 
    cat0_.name as name2_0_0_,
    cat0_.sex as sex3_0_0_,
    colors1_.cat_id as cat_id1_1_1_, 
    colors1_.color as color2_1_1_, 
    nicknames2_.cat_id as cat_id1_2_2_, 
    nicknames2_.nickname as nickname2_2_2_
  from cat cat0_ 
  left outer join cat_color colors1_ on cat0_.id=colors1_.cat_id 
  left outer join cat_nickname nicknames2_ on cat0_.id=nicknames2_.cat_id 
where cat0_.id=1
然后,Hibernate从cat表的行和两个表(表示CATColor和cat昵称集)中获取笛卡尔积

然后Hibernate遍历每一行,解析ResultSet的每一项并创建实体。是否有可能优化这种方法?由于严重的性能问题,我想通过子选择来选择CATColor和CAT昵称集。在实际情况中,我获取了1500个实体,这些实体具有复杂的结构,一个获取的实体在相应的ResultSet中生成了25000行,这导致了很长的解析时间


在我的例子中,延迟加载不是我想要使用的选项,因为它会给代码带来混乱。据我所知,延迟加载的集合必须通过第一次调用进行初始化,这在我的实际应用程序中是一个相当大的可用性代价


我希望有3个单独的选择,一个来自cat表,一个来自cat_颜色表,一个来自cat_昵称表。

我找到了Hibernate的解决方案,@fetchMode.SELECT完成了这项工作,因为它使Hibernate通过单独的选择而不是联接来选择昵称

@Fetch(FetchMode.SELECT)
@ElementCollection(fetch = FetchType.EAGER)
@Column(name = "nickname")
@CollectionTable(
        name = "cat_nickname",
        joinColumns = @JoinColumn(name = "cat_id"))
private Set<String> nicknames;

你跟踪的请求在我看来很好,它不是我所说的笛卡尔积。其他哪个SQL请求将检索单个cat的数据?如果您不需要特定用例的外围数据,可以通过FetchType.LAZY剪切一些连接。在我的用例中,延迟加载不是我想要使用的选项,因为它会给代码带来混乱。据我所知,延迟加载的集合必须通过第一次调用进行初始化,这在我的实际应用程序中是一个相当大的可用性代价。其他哪个SQL请求将检索单个cat的数据?我希望有3个单独的选择,一个来自cat表,一个来自cat_颜色表,一个来自cat_昵称表。是的,通过使用FetchType.LAZY并用代码触发选择,您可以进行这3个单独的选择。你不能同时拥有一件事和另一件事。
select cat0_.id as id1_0_0_, 
    cat0_.name as name2_0_0_,
    cat0_.sex as sex3_0_0_,
    colors1_.cat_id as cat_id1_1_1_, 
    colors1_.color as color2_1_1_, 
    nicknames2_.cat_id as cat_id1_2_2_, 
    nicknames2_.nickname as nickname2_2_2_
  from cat cat0_ 
  left outer join cat_color colors1_ on cat0_.id=colors1_.cat_id 
  left outer join cat_nickname nicknames2_ on cat0_.id=nicknames2_.cat_id 
where cat0_.id=1
id1_0_0_    name2_0_0_  sex3_0_0_   cat_id1_1_1_    color2_1_1_ cat_id1_2_2_    nickname2_2_2_
1   Ben Male    1   Black   1   Fluffy
1   Ben Male    1   Black   1   Catburger
1   Ben Male    1   Black   1   Mr. Tomcat
1   Ben Male    1   White   1   Fluffy
1   Ben Male    1   White   1   Catburger
1   Ben Male    1   White   1   Mr. Tomcat
@Fetch(FetchMode.SELECT)
@ElementCollection(fetch = FetchType.EAGER)
@Column(name = "nickname")
@CollectionTable(
        name = "cat_nickname",
        joinColumns = @JoinColumn(name = "cat_id"))
private Set<String> nicknames;