首页 > 解决方案 > Ebean中的条件@OnetoMany关系

问题描述

我有一个与parent实体有OneToMany关系的child实体。

我想定义这些之间的条件关系,其中childattribute一个值为 3 的列字段。attribute是表中的一个整数列,child就像在模型中一样:

@Constraints.Required
@NotNull
protected Integer attribute;

这是我在parent实体类中尝试过的:

@OneToMany(mappedBy = "parent")
@Where(clause = "attribute = 3")
List<Child> specificChildren;

然而,生成的查询忽略了我所做的 where 子句,并为我提供了与该父级相关的所有子级,而不仅仅是带有attribute = 3. 更改clause${ta}.attribute = 3也不成功。

这是生成的 SQL query.getGeneratedSql()

select distinct on (t1.attribute, t0.id) t0.id, t1.attribute
from parent t0
left join child t1 on t1.parent_id = t0.id
order by t1.someotherattribute

@Where属性被完全忽略,因为无论我用它做什么,生成的 SQL 都不会受到影响。

有一个io.ebean.annotation.Where类,所以它似乎应该能够工作,但我还没有找到任何关于它的 Ebean 特定文档(Ebean 的文档似乎确实有些缺乏)。我找到的关于@Where注释的大多数信息都与 Hibernate 相关。我确实在这里找到了它的源代码。

是否以这种方式支持?或者还有其他方法可以实现吗?

我目前正在使用 PostgreSQL 10.4、Ebean 10.4.4、Play 2.6.7,使用 Play 的 Ebean 插件 4.0.6。我尝试更新到 Play 的 Ebean 4.1.3,但没有成功。不确定我使用的版本是否应该受到指责。

更多信息可在此处的 Google 群组中找到。

标签: javapostgresqljpaone-to-manyebean

解决方案


它适用于我,所以请让我:

  1. 首先描述它在我身边的样子
  2. 然后提供关于您身边的问题的假设
  3. 然后问一些澄清问题(以防需要进一步的帮助)

工作解决方案

我使用过Ebean 10.4.4PostgreSQL 10(也适用于MySQL 6.7)。

  1. Employee类的主要部分,它是一个child实体:

    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;
    
    protected int attribute;
    
  2. 主要部分来自Department类,它是一个parent实体:

    @OneToMany(mappedBy = "department")
    @Where(clause = "attribute = 3")
    private List<Employee> employees = new ArrayList<Employee>();
    
  3. 查找查询

    Query<Department> query = Ebean.find(Department.class).fetch("employees")
            .where().eq("name", "DevOps").query();
    Department department = query.findUnique();
    String queryString = query.getGeneratedSql();
    System.out.println(queryString);
    

    这里的重要部分是热切地获取"employees"字段。结果输出如下所示:

    select t0.id, t0.name, t1.id, t1.name, t1.attribute_test, t1.department_id
    from department t0
    left join employee t1 on t1.department_id = t0.id
    where attribute_test = 3 and t0.name = ?
    order by t0.id
    

假设

主要假设(因为我不知道您是如何查询/搜索实体的)是您没有急切地获取child实体并且它们是使用单独的 SQL 获取的。

例如,在我上面的示例中,如果我将删除.fetch("employees")部分并将这样做:

Query<Department> query = Ebean.find(Department.class)
        .where().eq("name", "DevOps").query();
Department department = query.findUnique();
String queryString = query.getGeneratedSql();
System.out.println(queryString);
System.out.println(department); // uses this.employees in #toString() - so will lazily fetch child entities

我会有:

  • 下面的输出queryString

    select t0.id, t0.name from department t0 where t0.name = ?
    
  • 下一个输出department(我部门中有两名员工,attribute = 2一名员工attribute = 3):

    Department [
      id=1,
      name=java,
      employees=[{Employee [id=3, name=Batman, attribute=3, department=DevOps]}]
    ]
    
  • 以及日志中的 2 个 SQL 查询(此处使用Logback),一个用于查找部门,另一个用于获取员工(具有@Where相关逻辑):

    08:09:35.038 [main] DEBUG io.ebean.SQL - txn[1001] select t0.id, t0.name from department t0 where t0.name = ? ; --bind(java)
    08:09:35.064 [main] DEBUG io.ebean.SQL - txn[1002] select t0.department_id, t0.id, t0.name, t0.attribute_test, t0.department_id from employee t0 where attribute_test = 3 and (t0.department_id) in (?) ; --bind(1)
    

澄清问题

如果上述方法不起作用,您能否提供下一个信息:

  1. 使用的是哪个版本的 PostgreSQL?

  2. @ManyToOnechild实体端使用吗?

  3. 您能否提供由您的程序发起的 SQL 查询的日志?

    像这里描述的那样启用Logback就足够了>>:只需要添加依赖项并利用这个 >>配置文件。


推荐阅读