Ebean 中的条件@OnetoMany 关系
Conditional @OnetoMany relationship in Ebean
我有一个 parent
实体,它与 child
实体有 OneToMany
关系。
我想定义它们之间的条件关系,其中 child
有一个值为 3 的 attribute
列字段。attribute
是 [=15 中的整数列=] table 像模型中这样:
@Constraints.Required
@NotNull
protected Integer attribute;
这是我在 parent
实体中尝试的 class:
@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
class,所以看起来它应该可以工作,但我还没有找到关于它的任何 Ebean 特定文档(Ebean 的文档似乎有点不足)。我找到的关于 @Where
注释的大部分信息都与 Hibernate 相关。不过我确实找到了它的源代码 here。
这种方式支持吗?或者有其他方法可以实现吗?
我目前正在使用 PostgreSQL 10.4、Ebean 10.4.4、Play 2.6.7,使用 Play 的 Ebean 插件 4.0.6。我尝试更新到 Play 的 Ebean 4.1.3 但没有成功。不确定我使用的版本是否是罪魁祸首。
在 Google 组 here 中找到更多信息。
它对我有效,所以请让我:
- 先说说我这边的样子
- 然后就你这边的问题提供一个假设
- 然后问一些澄清问题(以防需要进一步的帮助)
工作解决方案
我使用了 Ebean 10.4.4 和 PostgreSQL 10(适用于 MySQL 6.7 也是)。
主要部分来自Employeeclass,是一个child
实体:
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
protected int attribute;
主要部分来自部门class,是一个parent
实体:
@OneToMany(mappedBy = "department")
@Where(clause = "attribute = 3")
private List<Employee> employees = new ArrayList<Employee>();
查找查询
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
假设
主要假设(因为我不知道你是如何 queried/searched 实体的)是你没有急切地获取 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)
澄清问题
如果上述方法不起作用,请提供以下信息:
我有一个 parent
实体,它与 child
实体有 OneToMany
关系。
我想定义它们之间的条件关系,其中 child
有一个值为 3 的 attribute
列字段。attribute
是 [=15 中的整数列=] table 像模型中这样:
@Constraints.Required
@NotNull
protected Integer attribute;
这是我在 parent
实体中尝试的 class:
@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
class,所以看起来它应该可以工作,但我还没有找到关于它的任何 Ebean 特定文档(Ebean 的文档似乎有点不足)。我找到的关于 @Where
注释的大部分信息都与 Hibernate 相关。不过我确实找到了它的源代码 here。
这种方式支持吗?或者有其他方法可以实现吗?
我目前正在使用 PostgreSQL 10.4、Ebean 10.4.4、Play 2.6.7,使用 Play 的 Ebean 插件 4.0.6。我尝试更新到 Play 的 Ebean 4.1.3 但没有成功。不确定我使用的版本是否是罪魁祸首。
在 Google 组 here 中找到更多信息。
它对我有效,所以请让我:
- 先说说我这边的样子
- 然后就你这边的问题提供一个假设
- 然后问一些澄清问题(以防需要进一步的帮助)
工作解决方案
我使用了 Ebean 10.4.4 和 PostgreSQL 10(适用于 MySQL 6.7 也是)。
主要部分来自Employeeclass,是一个
child
实体:@ManyToOne @JoinColumn(name = "department_id") private Department department; protected int attribute;
主要部分来自部门class,是一个
parent
实体:@OneToMany(mappedBy = "department") @Where(clause = "attribute = 3") private List<Employee> employees = new ArrayList<Employee>();
查找查询
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
假设
主要假设(因为我不知道你是如何 queried/searched 实体的)是你没有急切地获取 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)
澄清问题
如果上述方法不起作用,请提供以下信息: