即使在阅读文档之后,我似乎对 Google App Engine 的实体组也存在根本性的误解。我的目标是 ORM 的一个简单示例:我将一些员工分配到部门。一个员工只能分配到一个部门,但一个部门可以有多个员工。这是标准的一对多关系。
给定员工的密钥(电子邮件)和部门名称,我想同时查找员工和部门对象,如果它们不存在,则创建它们。
下面是伪代码,不是用来编译的。如果生成可以编译的代码可以帮助您帮助我,我很乐意这样做,但我认为我的问题是概念性的。
数据对象:
@Entity
public class Department {
private Key key;
private String name;
// getters and setters
}
@Entity
@NamedQuery(name="getEmployeesInDept", query="SELECT a from Employee a WHERE a.dept=:dept")
public class Employee {
private Key key;
private String firstName;
@ManyToOne
private Department dept;
// getters and setters
}
查找或创建
Key employeeKey = KeyFactory.createKey("Employee", email);
Employee employee = entityManager.find(Employee.class, employeeKey);
if(employee == null)
{
Key deptKey = KeyFactory.createKey("Department", deptName);
Department dept = entityManager.find(Department.class, deptKey);
if(dept == null)
{
dept = new Department();
dept.setKey(deptKey);
dept.setName(deptName);
entityManager.persist(dept);
}
employee = new Employee();
employee.setKey(employeeKey);
employee.setFirstName(firstName);
employee.setDept(dept);
entityManager.persist(employee);
}
entityManager.close();
print("Found employee " + employee.getFirstName() + " from " + dept.getName() + " department!");
在我尝试迁移到 Google App Engine 之前,当我使用古老的通用 ORM 时,这就是完美的逻辑。
但是,在 GAE 上,我得到一个例外,例如:
javax.persistence.PersistenceException:检测到尝试将 Employee("bob@mycompany.com") 建立为 Department(14) 的父级,但 Department(14) 标识的实体已在没有父级的情况下持久化。一旦对象被持久化,就不能建立或更改父对象。
虽然我知道为了让 Employee 和 Department 进入同一个实体组(我更喜欢),我必须让其中一个成为另一个的父级,但他们的关系并不是真正适合父子关系的关系我心中的范式。
我曾尝试在entityManager.getTransaction().begin()
和之间包装各个部分entityManager.getTransaction().end()
,但无济于事。
我可以通过将部门的密钥作为员工密钥的一部分来解决这个问题(从而使部门成为员工的父级),但是我不知道如何根据他们的电子邮件查找员工并弄清楚他们所在的部门,或者,相反,如何查找给定部门的所有员工。
这有意义吗?我应该如何在 GAE 中构建这种关系?当然,这是一种非常常见的模式,它有一个简单的解决方案,只是让我望而却步。
我确信我遗漏了这个难题的一些基本部分,因为在 GAE 的 ORM 中无法轻松表示简单的多对一外键似乎相当荒谬。
干杯!