Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate-运行时的筛选器关系_Java_Hibernate_Runtime_Filtering_Relation - Fatal编程技术网

Java hibernate-运行时的筛选器关系

Java hibernate-运行时的筛选器关系,java,hibernate,runtime,filtering,relation,Java,Hibernate,Runtime,Filtering,Relation,我有以下POJO: @Entity(name = "member") @Table(name = "member") public class Member { @Column(name = "identifier") @Id @GeneratedValue private int mIdentifier; @Column(name = "name", columnDefinition = "text") private String mName

我有以下POJO:

@Entity(name = "member")
@Table(name = "member")
public class Member {
    @Column(name = "identifier")
    @Id
    @GeneratedValue
    private int mIdentifier;

    @Column(name = "name", columnDefinition = "text")
    private String mName;

    @ManyToMany(mappedBy = "mMembers")
    private Set<Project> mProjects = new HashSet<Project>();

    public int getIdentifier() {
        return mIdentifier;
    }

    public String getName() {
        return mName;
    }

    public void setName(final String pName) {
        mName = pName;
    }

    public Set<Project> getProjects() {
        return mProjects;
    }

    public Member() {
    }
}
如何筛选项目的成员?例如,假设我只想要名称以“a”开头的成员。当然,我可以做一些客户端过滤(例如使用Guava&Predicate),但让Hibernate改变SQL查询更有意义

我知道,但我不认为他们是为了这个。我认为它们更适用于全局过滤,而不是特定对象的特殊关系过滤

非常欢迎向文档、术语等提供指导。我对Hibernate还比较陌生,很难获得这个问题的文档

编辑

我用标准试过了。我有两名成员,“约翰·斯诺”和“斯诺”。下面仍然返回两个成员

final Criteria criteria = db.createCriteria(Project.class)
        .createCriteria("mMembers")
        .add(Restrictions.eq("mName", "John Snow"));

for (final Project project : (List<Project>) criteria.list()) {
    System.out.println(project.getIdentifier());

    for (final Member member : project.getMembers()) {
        System.out.println(member.getName());
    }
}
编辑(3)

看看上面的第一个查询,这并不是我想要的。本质上,我想要两个问题:

  • 第一个查询获取某个项目。此查询从表项目中选择
  • 第二个查询获取符合特定条件的所有成员。当调用
    getMembers()
    时,将延迟执行此查询。此查询从表成员中选择,并在项目成员上联接
  • 我不想将其合并到一个查询中并从表project_成员中选择,因为这将导致大量解析开销。我不想以笛卡尔积结束


    这可能吗?

    新的JPA 2.1规定了在连接中按条件使用的可能性:

    select p from Project p left join p.members m ON m.name like 'a%'
    

    正如我在评论中提到的,我建议在hibernate中研究标准和/或hql文档。举个简单的例子,根据条件,您可以执行以下操作(我假设Spring的会话工厂,但api在其他地方是相同的):

    如果您希望在项目中获得不同的结果,也很容易,只需再添加一种方法:

    List filteredProjects = criteria.createAlias("member", "member")
            .add( Restrictions.ilike("member.mName", "a", MatchMode.ANYWHERE) )
            .setProjection(Projections.distinct(Projections.property("mIdentifier"))) //this will make distinct on your id property
            .list();
    
    使用HQL,第二个查询如下所示:

    List projects = session.createQuery("select distinct p from Project p join p.mMembers as m where m.mName like :param")
           .setParameter("param", "%a%")
           .list();
    
    @Entity(name = "project")
    @Table(name = "project")
    public class Project {
        @Column(name = "identifier")
        @Id
        @GeneratedValue
        private int mIdentifier;
    
        @ManyToMany(cascade = CascadeType.ALL)
        private Set<Member> mMembers = new HashSet<Member>();
    
        public int getIdentifier() {
            return mIdentifier;
        }
    
        public Set<Member> getMembers() {
            return mMembers;
        }
    
        public Project() {
        }
    
        @Formula("<YOUR SQL TO FILTER RESULT>")
        @Basic(fetch=FetchType.LAZY) 
        public Set<Member> getFilteredMembers() {
            return mMembers
        }
    }
    
    编辑:您想要的功能如下所示:

    List projects = session.createQuery("select distinct p from Project p join p.mMembers as m where m.mName like :param")
           .setParameter("param", "%a%")
           .list();
    
    @Entity(name = "project")
    @Table(name = "project")
    public class Project {
        @Column(name = "identifier")
        @Id
        @GeneratedValue
        private int mIdentifier;
    
        @ManyToMany(cascade = CascadeType.ALL)
        private Set<Member> mMembers = new HashSet<Member>();
    
        public int getIdentifier() {
            return mIdentifier;
        }
    
        public Set<Member> getMembers() {
            return mMembers;
        }
    
        public Project() {
        }
    
        @Formula("<YOUR SQL TO FILTER RESULT>")
        @Basic(fetch=FetchType.LAZY) 
        public Set<Member> getFilteredMembers() {
            return mMembers
        }
    }
    
    @实体(name=“项目”)
    @表(name=“项目”)
    公共类项目{
    @列(name=“identifier”)
    @身份证
    @生成值
    私有内部标识符;
    @多个(级联=级联类型.ALL)
    私有集mMembers=new HashSet();
    公共int getIdentifier(){
    返回中间层;
    }
    公共集getMembers(){
    返回mMembers;
    }
    公共工程(){
    }
    @公式(“”)
    @基本(fetch=FetchType.LAZY)
    公共集getFilteredMembers(){
    返回成员
    }
    }
    

    但是根据这一点:您需要一些额外的工作来让它惰性地工作。

    那么,标准或hql呢我会研究这个!谢谢谢谢你的回答。请参阅我的编辑。我尝试了类似的标准(我没有包括别名),但没有成功。你知道吗?什么样的SQL是用双createCriteria生成的?我不确定这是否是正确的连接方式,请尝试使用别名,而不是查看编辑(2)!我也尝试过使用别名,但第二个查询总是发生。我刚刚意识到,您的getter/setter不遵循java约定。试着把它做好,然后再试一次,你能详细说明一下吗?
    List projects = session.createQuery("select distinct p from Project p join p.mMembers as m where m.mName like :param")
           .setParameter("param", "%a%")
           .list();
    
    @Entity(name = "project")
    @Table(name = "project")
    public class Project {
        @Column(name = "identifier")
        @Id
        @GeneratedValue
        private int mIdentifier;
    
        @ManyToMany(cascade = CascadeType.ALL)
        private Set<Member> mMembers = new HashSet<Member>();
    
        public int getIdentifier() {
            return mIdentifier;
        }
    
        public Set<Member> getMembers() {
            return mMembers;
        }
    
        public Project() {
        }
    
        @Formula("<YOUR SQL TO FILTER RESULT>")
        @Basic(fetch=FetchType.LAZY) 
        public Set<Member> getFilteredMembers() {
            return mMembers
        }
    }