Spring Data / JPS(N + 1)SELECT与OneToOne关联

时间:2016-03-15 20:07:20

标签: spring jpa spring-data spring-data-jpa querydsl

在我的Spring Data应用程序中,我遇到了(N + 1)选择问题。

我有以下Spring Data实体:

@Entity
@Table(name = "card_categories")
public class CardCategory extends BaseEntity implements Serializable {

    @Id
    @SequenceGenerator(name = "card_categories_id_seq", sequenceName = "card_categories_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "card_categories_id_seq")
    private Long id;

    private String name;
...

}

@Entity
@Table(name = "levels")
public class Level extends BaseEntity implements Serializable {

    @Id
    @SequenceGenerator(name = "levels_id_seq", sequenceName = "levels_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "levels_id_seq")
    private Long id;

    private String name;
...
}

@Entity
@Table(name = "card_categories_levels")
public class CardCategoryLevel extends BaseEntity implements Serializable {

    @Id
    @SequenceGenerator(name = "card_categories_levels_id_seq", sequenceName = "card_categories_levels_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "card_categories_levels_id_seq")
    private Long id;

    @OneToOne
    @JoinColumn(name = "card_category_id")
    private CardCategory cardCategory;

    @OneToOne
    @JoinColumn(name = "level_id")
    private Level level;
...

}

并清空Spring Data存储库:

@Repository
public interface CardCategoryLevelRepository extends JpaRepository<CardCategoryLevel, Long> {
}

当我尝试通过CardCategoryLevel方法获取所有cardCategoryLevelRepository.findAll()实体时,它会为card_categories_levels表中的每一行生成3个SELECT。

为了使用一个JOIN而不是N + 1个SELECT,我重新实现了CardCategoryLevelRepository

@Repository
public interface CardCategoryLevelRepository extends JpaRepository<CardCategoryLevel, Long> {

    @Query(value = "SELECT ccl FROM CardCategoryLevel ccl LEFT JOIN FETCH ccl.cardCategory cc LEFT JOIN FETCH ccl.level l where cc = :cardCategory and l = :level")
    CardCategoryLevel findByCardCategoryAndLevel(@Param("cardCategory") CardCategory cardCategory, @Param("level") Level level);

    @Override
    @Query(value = "SELECT ccl FROM CardCategoryLevel ccl LEFT JOIN FETCH ccl.cardCategory LEFT JOIN FETCH ccl.level")
    List<CardCategoryLevel> findAll();

}

但我不确定我是以正确的最佳方式做到的。

请验证我的方法,并告诉它是Spring数据中OneToOne关联的(N + 1)SELECT问题的最佳解决方法,或者没有,解决问题的最佳方法是什么。

我应该保留原样,还是可以转移到其他抽象中......例如像QueryDSL或类似的东西?

1 个答案:

答案 0 :(得分:0)

感谢Xtreme Biker我已使用实体图和QueryDSL重新实现了我的解决方案