2016-08-02 8 views
0

Hallo Ich habe eine App mit Hibernate/JPA und Spring Data. Ich habe 2 Entitäten mit einer Eltern-Kind-Beziehung mit einer Beziehung von eins zu viele. Sie sind unter:Hibernate Elternkreis zum Abrufen von Kindern

dies ist die Mutter:

@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; 
    ... 
} 

und das ist das Kind:

@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; 

Im Folgenden ist der Spring Data Repository I erstellt:

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); 
} 

Wenn ich die findAll() Methode des Repositorys anrufe merke ich, dass Hibern Zuerst ruft atet alle Eltern ab, führt dann eine Schleife durch jedes Elternteil und führt eine Abfrage pro Elternteil durch, um die Kinder abzurufen. Ich kann mir nicht vorstellen, dass Hibernate nicht nur 1 Abfrage ausführt, um die Eltern und die Kinder auf einmal abzurufen stürzen und entsenden den Rekord entsprechend.

unten wird der Ausschnitt aus dem Protokoll (kommentiert mit eigenen Kommentaren)

//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=? 
... 

Jede Idee, wie man schlauer über diese Fragen Hibernate helfen? (Wenn ich dies schreiben waren in rohen SQL ich den Datensatz beitreten würde, Benutzer und dataset_file alle in einer Abfrage, es ist ein Vielfaches schneller.

Danke

Antwort

0

Sie verwenden gespannt auf Ihre datasetFiles geladen, damit Ihr Persistenz-Provider wird eifrig Ihre datasetFiles laden holen, weil Sie es als EAGER gesetzt Strategie holen. Standardmäßig wird die Strategie holen für @OneToMany in JPA LAZY wird. Nur nicht setzen die fetch Strategie und die Persistenz-Provider LAZY es für Sie laden.

+0

Aber ich möchte alle Dataset_files geladen werden, wenn ich die Datensätze lese, aber loadin g Die Dataset_files als Schleife durch die Datensätze scheint mir sehr naiv. Ein einziger Join, um diese Arbeit zu tun, ist Größen schneller. Beispiel: Wählen Sie a. *, b. * aus dem Dataset einer inneren Verknüpfung dataset_file b auf a.id = b.dataset_id; –

+0

Warum möchten Sie Ihre Dataset_Dateien auf einmal laden? Vergessen Sie nicht, dass Sie mit der LAZY-Strategie dem Persistenzanbieter mitteilen, dass die Sammlung zuerst die Daten laden muss und die gesammelte Entität dann an den Client zurückgeben muss. –

Verwandte Themen