【问题标题】:Hibernate Criteria, group/select distinct children of a parent休眠标准,分组/选择父母的不同孩子
【发布时间】:2015-04-19 21:27:07
【问题描述】:

我有一个模型父级,它有一个子级列表(列表

class Parent {
   @OneToMany(targetEntity = Child.class, cascade = CascadeType.ALL, mappedBy = "parent")
   @JsonManagedReference
   private List<Child> tags =  new ArrayList<>();

   @Column(name = "name")
   public String name;

}

class Child {
     @Column(name = "name")
     public String name;

     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "parent_id", nullable = true)
     @JsonBackReference
     private Parent parent;
}

我在 EAGER 模式下选择了一个包含孩子的父母列表 (List )。

现在孩子可以有相同的名字,但我不希望同名的孩子在列表中不止一次。 有什么建议如何让同名的孩子在集合中只出现一次?

【问题讨论】:

  • 您应该使用 Java Set 存储您的 Child 列表;此外,您的 equalshasCode(对于该实体)的实现也很重要
  • 数据库是否允许重复名称?如果没有,请考虑使用@Column(name = "name", unique=true)
  • @Machina 是的,但是如何从 Hibernate Criteria 返回一个集合?
  • @Shahzeb - 是的,数据库允许重复名称。
  • @Sergiu,我在这里看到了一些不匹配:您可以在数据库中有许多具有相同/重复名称的 chils,您可以将这些(甚至重复)与同一个父级关联。由于没有办法(AFAIK)从 Hibernate 条件查询中返回 Set,我建议您使用类似:setProjection(Projections.distinct(Projections.property("name")))...并且仍然在您的模型中使用 Set

标签: java hibernate hibernate-criteria hibernate-4.x


【解决方案1】:

这是使用set 删除重复值的示例代码。如果 firstName 存在,则忽略第二个条目。可以根据自己的需要修改。

但是,虽然这是您所提问题的答案,但请注意这里有一股代码味道。 他们认为您必须在代码中执行此操作,而数据库允许这样做是有问题的,并且几乎可以保证存在设计缺陷。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Test
{
    private String firstName;
    private String lastName;


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((firstName == null) ? 0 : firstName.hashCode());
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Test other = (Test) obj;
        if (firstName == null) {
            if (other.firstName != null)
                return false;
        } else if (!firstName.equals(other.firstName))
            return false;
        return true;
    }


    public Test(String firstName, String lastName) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
    }


    public static void main(String[] args)
    {
        List<Test> aList = new ArrayList<Test>();
        Test test1 = new Test("Tom","Hardy");
        Test test2 = new Test("Tom","Cruise");
        Test test3 = new Test("Any","Body");
        aList.add(test1);
        aList.add(test2);
        aList.add(test3);

        System.out.println("List values:");
        for (Test test : aList)
        {
            System.out.println(test.firstName + "-"+ test.lastName);
        }
        Set<Test> alphaSet = new HashSet<Test>(aList);
        System.out.println("Set values:");
        for (Test test : alphaSet)
        {
            System.out.println(test.firstName + "-"+ test.lastName);
        }
    }
}

【讨论】:

  • 感谢您的回答。我觉得这非常有用。我同意设计缺陷。我找到了一个很好的解决我的问题的方法,我将设置一个 manyToMany 父子关系,这将消除重复。我不知道为什么我没有早点想到这个。谢谢!
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
  • 2015-05-09
相关资源
最近更新 更多