hibernate父循环来获取子项

时间:2016-08-02 14:57:01

标签: hibernate jpa spring-data-jpa

您好我有一个使用Hibernate / JPA和Spring Data的应用程序。 我有2个具有父子关系的实体,具有一对多的关系。 他们在下面:

这是父母:

@Entity
@Table(name = "dataset")
public class Dataset {

    @Id
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    private Long id;
    @Column(name = "name", nullable = false)
    private String name;
    @Column(name = "guid", nullable = false)
    private String guid;
    @Column(name = "size", nullable = false)
    private Long size;
    @Column(name = "create_time", nullable = false)
    private Date createTime;
    @OneToOne(optional = false)
    @JoinColumn(name = "created_by")
    private User createdBy;
    @Column(name = "active", nullable = false)
    private boolean active;
    @Column(name = "orig_source", nullable = false)
    private String origSource;
    @Column(name = "orig_source_type", nullable = false)
    private String origSourceType;
    @Column(name = "orig_source_org", nullable = false)
    private String origSourceOrg;
    @Column(name = "uri", nullable = false)
    private String uri;
    @Column(name = "mimetype", nullable = false)
    private String mimetype;
    @Column(name = "registration_state", nullable = false)
    private int registrationState;
    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @JoinColumn(name = "dataset_id")
    @JsonManagedReference
    private List<DatasetFile> datasetFiles;
    ...
}

这就是孩子:

@Entity
@Table(name = "dataset_file")
public class DatasetFile implements Serializable {

    @Id
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    private Long id;
    @Column(name = "filename", nullable = false)
    private String filename;
    @Column(name = "filesize", nullable = false)
    private Long filesize;
    @Column(name = "location", nullable = false)
    private String uri;
    @Column(name = "alias", nullable = false)
    private String alias;
    @Column(name = "guid", nullable = false)
    private String guid;
    @Column(name = "mimetype", nullable = false)
    private String mimetype;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "dataset_id")
    @JsonBackReference
    private Dataset dataset;

以下是我创建的Spring Data存储库:

public interface DatasetRepo extends JpaRepository<Dataset, Long> {

    @Query("SELECT CASE WHEN COUNT(p) > 0 THEN 'true' ELSE 'false' END FROM Dataset p WHERE p.uri = ?1")
    public Boolean existsByURI(String location);
}

当我调用存储库的findAll()方法时,我注意到Hibernate首先获取所有父节点,然后遍历每个父节点并为每个父节点运行查询以获取子节点,我可以& #39;想象一下Hibernate不知道只运行1个查询来一次性获取父母和孩子,并相应地取消记录集。

下面的

是日志中的片段(用我自己的评论注释)

//this is where it fetches the data set
Hibernate: select dataset0_.id as id1_1_, dataset0_.active as active2_1_, dataset0_.create_time as create_t3_1_, dataset0_.created_by as created13_1_, dataset0_.guid as guid4_1_, dataset0_.mimetype as mimetype5_1_, dataset0_.name as name6_1_, dataset0_.orig_source as orig_sou7_1_, dataset0_.orig_source_org as orig_sou8_1_, dataset0_.orig_source_type as orig_sou9_1_, dataset0_.registration_state as registr10_1_, dataset0_.size as size11_1_, dataset0_.uri as uri12_1_ from dataset dataset0_

//this is where it fetches the create user
Hibernate: select user0_.id as id1_5_1_, user0_.active as active2_5_1_, user0_.fn as fn3_5_1_, user0_.home_div as home_div4_5_1_, user0_.ln as ln5_5_1_, user0_.mi as mi6_5_1_, user0_.password as password7_5_1_, user0_.username as username8_5_1_, authoritie1_.id_user as id_user1_5_3_, authority2_.id as id_autho2_6_3_, authority2_.id as id1_0_0_, authority2_.name as name2_0_0_ from user user0_ left outer join users_authority authoritie1_ on user0_.id=authoritie1_.id_user left outer join authority authority2_ on authoritie1_.id_authority=authority2_.id where user0_.id=?

//this is where it fetch dataset files
Hibernate: select datasetfil0_.dataset_id as dataset_8_1_1_, datasetfil0_.id as id1_2_1_, datasetfil0_.id as id1_2_0_, datasetfil0_.alias as alias2_2_0_, datasetfil0_.dataset_id as dataset_8_2_0_, datasetfil0_.filename as filename3_2_0_, datasetfil0_.filesize as filesize4_2_0_, datasetfil0_.guid as guid5_2_0_, datasetfil0_.mimetype as mimetype6_2_0_, datasetfil0_.location as location7_2_0_ from dataset_file datasetfil0_ where datasetfil0_.dataset_id=?
    Hibernate: select datasetfil0_.dataset_id as dataset_8_1_1_, datasetfil0_.id as id1_2_1_, datasetfil0_.id as id1_2_0_, datasetfil0_.alias as alias2_2_0_, datasetfil0_.dataset_id as dataset_8_2_0_, datasetfil0_.filename as filename3_2_0_, datasetfil0_.filesize as filesize4_2_0_, datasetfil0_.guid as guid5_2_0_, datasetfil0_.mimetype as mimetype6_2_0_, datasetfil0_.location as location7_2_0_ from dataset_file datasetfil0_ where datasetfil0_.dataset_id=?
    Hibernate: select datasetfil0_.dataset_id as dataset_8_1_1_, datasetfil0_.id as id1_2_1_, datasetfil0_.id as id1_2_0_, datasetfil0_.alias as alias2_2_0_, datasetfil0_.dataset_id as dataset_8_2_0_, datasetfil0_.filename as filename3_2_0_, datasetfil0_.filesize as filesize4_2_0_, datasetfil0_.guid as guid5_2_0_, datasetfil0_.mimetype as mimetype6_2_0_, datasetfil0_.location as location7_2_0_ from dataset_file datasetfil0_ where datasetfil0_.dataset_id=?
    Hibernate: select datasetfil0_.dataset_id as dataset_8_1_1_, datasetfil0_.id as id1_2_1_, datasetfil0_.id as id1_2_0_, datasetfil0_.alias as alias2_2_0_, datasetfil0_.dataset_id as dataset_8_2_0_, datasetfil0_.filename as filename3_2_0_, datasetfil0_.filesize as filesize4_2_0_, datasetfil0_.guid as guid5_2_0_, datasetfil0_.mimetype as mimetype6_2_0_, datasetfil0_.location as location7_2_0_ from dataset_file datasetfil0_ where datasetfil0_.dataset_id=?
    Hibernate: select datasetfil0_.dataset_id as dataset_8_1_1_, datasetfil0_.id as id1_2_1_, datasetfil0_.id as id1_2_0_, datasetfil0_.alias as alias2_2_0_, datasetfil0_.dataset_id as dataset_8_2_0_, datasetfil0_.filename as filename3_2_0_, datasetfil0_.filesize as filesize4_2_0_, datasetfil0_.guid as guid5_2_0_, datasetfil0_.mimetype as mimetype6_2_0_, datasetfil0_.location as location7_2_0_ from dataset_file datasetfil0_ where datasetfil0_.dataset_id=?
...

知道如何帮助Hibernate更智能地解决这些问题吗? (如果我在原始SQL中写这个,我在一个查询中加入数据集,用户和dataset_file,它的速度要快很多倍。

谢谢

1 个答案:

答案 0 :(得分:0)

您正在使用急切加载datasetFiles,因此您的持久性提供商会急切地抓取您的datasetFiles,因为您将其设置为EAGER获取策略。默认情况下,JPA中@OneToMany的抓取策略为LAZY。只是不设置fetch策略,持久性提供程序将为您加载它。