JPA按多列对多列的顺序排列

问题描述:

我的问题比第一眼所描述的要复杂一点。让我试着解释一下。 我有两个实体单向多对多关系:JPA按多列对多列的顺序排列

public class Category implements Serializable { 

    @Id 
    @Column(name = "ct_id") 
    @SequenceGenerator(name = "category_ct_id_seq", sequenceName = "category_ct_id_seq", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "category_ct_id_seq") 
    private Long id; 

    @Column(name = "ct_name_key") 
    private String nameKey; 

    @ManyToMany 
    @JoinTable(name = "category_2_country", 
      joinColumns = @JoinColumn(name = "c2c_category_id"), 
      inverseJoinColumns = @JoinColumn(name = "c2c_country_id")) 
    private Set<Country> countries; 
} 

public class Country { 

    @Id 
    @SequenceGenerator(name = "country_c_id_seq", sequenceName = "country_c_id_seq", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "country_c_id_seq") 
    @Column(name = "c_id") 
    private Long id; 

    @Column(name = "c_name") 
    private String name; 

    @Column(name = "c_iso_2_alpha") 
    private String isoAlpha2Code; 

而且我通过国家的ISO代码(实际上,所有类别,这与被请求国的关系)检索分类收集。为此我写了一个规范:

public class CategorySpecification implements Specification<Category> { 

    Country matchCountry; 

    @Override 
    public Predicate toPredicate(Root<Category> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) { 

     return builder.isMember(matchCountry, root.get("countries")); 

    } 
} 

这工作得很好。问题是我需要为每个国家的类别订购优先级。 过渡表如下所示: enter image description here 因此,当我检索给定国家的类别集合时,我希望根据此sort_order列对其进行排序。

相应的SQL查询看起来是这样,像这样的事情:

SELECT * 
FROM category 
    JOIN category_2_country ON category.ct_id = category_2_country.c2c_category_id 
WHERE c2c_country_id = ? 
ORDER BY sort_order; 

但我应该怎么做它在我的JPA实体?我该如何将它保存到数据库中,这个顺序需要动态改变(例如从管理面板)?

编辑:在数据库表 对应的实体:

的一个国家 Country

而一个用于类别:

EDITED 2: 我已经成功地使用本机查询实现期望的行为,如下所示:

@Repository 
public interface CategoryRepository extends JpaRepository<Category, Long>, JpaSpecificationExecutor<Category> { 

    @Query(value = "SELECT ct.*\n" + 
      "FROM category ct\n" + 
      " JOIN category_2_country c2c ON ct.ct_id = c2c.c2c_category_id\n" + 
      " JOIN country c ON c2c.c2c_country_id = c.c_id\n" + 
      "WHERE c.c_iso_2_alpha = :countryIso\n" + 
      "ORDER BY c2c.sort_order", nativeQuery = true) 
    List<Category> findCategoriesForCountryOrdered(@Param("countryIso") String countryIso); 
} 

但还是希望有当你使用你正在使用JpaRepositoryJpaSpecificationExecutor规格做这件事情

+1

[This](http://*.com/questions/5127129/mapping-many-to-many-association-table-with-extra-columns)可能会有所帮助。 –

+0

我之前看到过这个线程,但仍然希望比仅仅因为优先级列重构所有实体更简单的解决方案 – DruidKuma

更JPA /休眠方式。 JpaSpecificationExecutor API给我们一个方法findAll(Specification<T> spec, Sort sort)

使用Sort类,您可以指定您想要对结果列表进行排序的属性(和方向)。

下面是文档:Sort

编辑: 一些搜索后 - 不幸的是,没有映射关联表进入休眠,你不能命令由/排序sort_order财产。这与JPQL有关,只能对实体中的映射属性起作用 - 如果不映射它们,则无法到达DB中的表。

因此,您可以映射关联表并创建规范,该规范将两个表连接起来,并通过sort_order创建排序。

+0

感谢您的一个很好的答案。但我无法传递给排序只是数据库列的名称。它必须是“类别”或“国家”的财产,但不能是许多表格中的列名称。可能是因为我没有任何选择,而不是将我的ManyToMany表变成单独的实体? :( – DruidKuma

+0

你必须从映射的实体传递一个变量名,在你的例子中:'country.sortOrder'假设'Country'类具有'sortOrder'字段,这是否正确? – ByeBye

+0

不幸的是,sortOrder具体而言不是国家,而是国家/地区映射 – DruidKuma