【问题标题】:Java \ Hibernate \ ManyToOne \ OrderingJava \ Hibernate \ ManyToOne \ Ordering
【发布时间】:2015-03-03 16:53:34
【问题描述】:

我对 Hibernate (JPA)、PostgreSQL 和排序有一些问题。

例如,我们有两个表(映射到实体):

- Pets (id (id), PetTypes (types_id), description (description))

- PetTypes (id (id), name (name))

type_id 字段不是必需的(仅限于 pet_types 表)。

例如,我们在 pets 表中有 10 行(第 1、2 和 3 行 type_id 为空)。我需要使用 HQL 或 JPA 标准按 pet_types.name 订购宠物表(但我认为 JPA 不支持)。

问题:如果 type_id 为 null,则 pets 表中的值不会按顺序选择。 我可以尝试使用下一个解决方案:

  1. FROM Pets pets ORDER BY pets.petTypes.name ASC NULLS LAST
  2. FROM Pets pets ORDER BY CASE WHEN pets.petTypes IS NULL THEN 0 ELSE 1 END, ORDER BY pets.petTypes.name ASC NULLS LAST
  3. FROM Pets pets ORDER BY CASE WHEN pets.petTypes.name IS NULL THEN 0 ELSE 1 END, ORDER BY pets.petTypes.name ASC NULLS LAST
  4. FROM Pets pets 左连接 pets.petTypes ORDER BY pets.petTypes.name ASC NULLS LAST
  5. FROM Pets pets ORDER BY pets.petTypes ASC NULLS LAST,pets.petTypes.names ASC
  6. 当 pets.petTypes 为 NULL 或 pets.petTypes.name 为 NULL THEN 0 ELSE 1 END 时,从 Pets 宠物按大小写排序,按 pets.petTypes.name ASC 排序

但是没有任何效果。选择后我们有 7 行而不是 10 行。有任何想法吗? 我不能通过 HQL 使用 UNION 语句。它从 2005 年开始开放 Hibernate bug

编辑

谢谢Rodrigo Menezes。此解决方案有效:

select p from Pets p left join p.petTypes pt order by case when pt is null then 0 else 1 end, pt.name

【问题讨论】:

  • 会不会是你需要两个订单(不确定)。因为“pets.petTypes”为空,不是pets.petTypes.name 还是?类似于 ORDER BY pets.petTypes ASC NULLS LAST, pets.petTypes.names ASC
  • 是的,我尝试使用这种方法。没有任何效果。我更新了上面的问题。
  • 排序顺序应该对行数没有影响。您可以发布原始 SQL 转储吗?
  • Hibernate 为 Pets 和 PetTypes 表生成 CROSS JOIN 语句

标签: java hibernate postgresql


【解决方案1】:

也许您的 HQL 正在生成内部联接或交叉联接。

你可以强制左连接:

select p from Pets p 
left join p.petTypes pt 
order by case when pt is null then 0 else 1 end, pt.name

我做了一个案例测试并工作:

public static void main(String[] args) {
    Session session = HibernateUtil.getSessionFactory().openSession();

    session.beginTransaction();

    PetTypes dog = new PetTypes();
    dog.setName("Dog");
    dog.setId(1);
    PetTypes cat = new PetTypes();
    cat.setName("Cat");
    cat.setId(2);

    session.save(dog);
    session.save(cat);

    int id = 1;
    Pets joe = new Pets();
    joe.setId(id++);
    joe.setDescription("Joe");

    Pets x = new Pets();
    x.setId(id++);
    x.setDescription("Sarah");    
    x.setPetTypes(dog);

    Pets y = new Pets();
    y.setId(id++);
    y.setDescription("Jakob");    
    y.setPetTypes(cat);  

    Pets z = new Pets();
    z.setId(id++);
    z.setDescription("Xena");    
    z.setPetTypes(cat);                

    session.save(joe);
    session.save(x);
    session.save(y);
    session.save(z);

    session.getTransaction().commit();

    Query q = session.createQuery("select p from Pets p "
            + "left join p.petTypes pt "
            + "order by case when pt is null then 0 else 1 end, pt.name ");

    List<Pets> resultList = q.list();
    System.out.println("num of employess:" + resultList.size());
    for (Pets next : resultList) {
        System.out.println("pet " + next);
    }
}

结果:

num of pets:4 
pet Pets [description=Joe, petTypes=null] 
pet Pets [description=Jakob, petTypes=PetTypes [name=Cat]] 
pet Pets [description=Xena, petTypes=PetTypes [name=Cat]] 
pet Pets [description=Sarah, petTypes=PetTypes [name=Dog]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2019-02-24
    • 2016-03-08
    • 1970-01-01
    相关资源
    最近更新 更多