2015-10-08 5 views
0

В моем приложении Spring JPA/MySQL данных У меня есть следующие entites:OneToOne Spring JPA MySQL LAZY нагрузки N + 1 выбирает

public class Gene implements Serializable { 

    @Id 
    @Column(name = "uid") 
    private String uid; 

    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "gene") 
    private GeneStory geneStory; 

} 

и

public class GeneStory implements Serializable { 

    @OneToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "gene_uid", referencedColumnName = "uid") 
    private Gene gene; 

} 

Я пытаюсь загрузить все Gene через

Query q = em.createQuery("select g from Gene g") 
return q.getResultList(); 

и я получаю N+1 selects problem с GeneStory

Сейчас на каждом Gene в базе данных у меня есть дополнительный запрос для GeneStory как следующее:

select genestory0_.story_id as story_id1_7_0_ ... from gene_stories genestory0_ where genestory0_.gene_uid=? 

Ленивый нагрузка GeneStory не работает по какой-то причине.

На уровне базы данных в gene_storie сек таблице У меня также есть ограничение -

CONSTRAINT `fk_gene_stories_gene_uid` 
    FOREIGN KEY (`gene_uid`) 
    REFERENCES `gene` (`uid`) 

Как это исправить N + 1 выбирает проблему? Я не хочу загружать GeneStory вместе с Gene. Мне нужно лениво загружать их, когда это необходимо.

ответ

1

Per JPA Spec:

Ленивый выборка намек поставщику настойчивость и может быть определено с помощью Basic, OneToOne, OneToMany, ManyToOne, ManyToMany и ElementCollection аннотаций и их XML эквиваленты

Стратегия EAGER является обязательным условием для поставщика непрерывности , в котором данные должны быть получены с нетерпением. Стратегия LAZY - это подсказка для среды выполнения поставщика, которая должна быть получена с ленивым , когда к ней впервые обращаются. Реализация разрешается с нетерпением выборка данных, для которых указана подсказка стратегии LAZY.

+0

Другими словами, нет возможности реализовать обычную двунаправленную ленивую нагрузку для OneToOne в JPA? – alexanoid

+1

Как сказано в спецификации, даже если вы указали LAZY fetch на аннотации, это всего лишь подсказка для вашего провайдера. Поставщик должен следить за подсказкой или переопределять ее, пытаясь извлечь данные. Когда я говорю «провайдер», мы говорим о любой реализации ORM, которая соответствует спецификации JPA (т. Е. Hibernate, EclipseLink и т. Д.). – Ish

Смежные вопросы