我正在 Play Framework 2.0.1 中探索 JPA 和 Ebean,以研究本地关系数据库中生成的内容。在我的测试中,我使用 MariaDB,MySQL 的一个分支。
到目前为止,我已经能够使用模型中的 JPA 注释在数据库中成功生成表。我想确保我学会了如何设置一个实体与另一个实体之间的一对一关系,以及如何与另一个实体建立一对多关系。
OneToOne:员工
有地址
OneToMany:员工
有宠物
我设置了一个小型应用程序,它允许我快速填充表、显示一些信息以及从表中删除行。对于那些想要查看我的设置的人来说,这是下面的代码:
路线
GET / controllers.Application.index()
GET /add controllers.Application.addEmployee()
GET /delete/:id controllers.Application.deleteEmployee(id: Long)
GET /employee/:id controllers.Application.showEmployee(id: Long)
Controller
应用程序.java
public class Application extends Controller {
public static Result index() {
return ok(index.render("entry point"));
}
public static Result addEmployee() {
// Create an employee.
Employee employee = new Employee();
employee.firstName = "John";
employee.lastName = "Doe";
employee.salary = new BigDecimal(123456);
// Create an address for the employee.
Address address = new Address();
address.city = "West Chester";
address.country = "United States of America";
address.postalCode = "19380";
address.province = null;
address.street = "45 Jingleheimer Drive";
// Create pets for the employee.
Pet pet = new Pet();
pet.petString = "dog";
Pet pet2 = new Pet();
pet2.petString = "cat";
employee.address = address;
employee.pets.add(pet);
employee.pets.add(pet2);
employee.save();
return ok(index.render("added an employee"));
}
public static Result showEmployee(Long id) {
Employee e = Employee.get(id);
//String s = e.address.street;
return ok(employee.render(e));
}
public static Result deleteEmployee(Long id) {
Employee.delete(id);
return ok(index.render("deleted employee " + id));
}
}
型号
员工.java
@Entity
public class Employee extends Model {
@Id
public Long employee_id;
public String firstName;
public String lastName;
public BigDecimal salary;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="owner_id")
public Address address;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="owner_id", referencedColumnName="employee_id")
public List<Pet> pets;
public static Employee get(Long id) {
return find.byId(id);
}
public static void delete(Long id) {
find.byId(id).delete();
}
public static Finder<Long, Employee> find = new Finder<Long,Employee>(Long.class, Employee.class);
}
地址.java
@Entity
public class Address extends Model {
@Id
public Long address_id;
public String street;
public String city;
public String province;
public String country;
public String postalCode;
}
Pet.java
@Entity
public class Pet extends Model {
@Id
public Long pet_id;
public String petString;
}
观看次数
employee.scala.html
@(employee: models.Employee)
@import helper._
@main("employee view") {
<p>@employee.firstName</p>
<p>@employee.lastName</p>
<p>@employee.salary</p>
<p>@employee.address.country</p>
<p>@employee.pets(1).petString</p>
@for(pet <- employee.pets) {
<p>@pet.petString</p>
}
}
如果我使用 localhost:9000/employee/1 这样的 URL 呈现上面的 View ,我会在浏览器中显示以下内容:
John
Doe
123456
cat
dog
cat
请注意,地址的国家/地区未显示。我还尝试在 Controller 中访问它并将其打印到命令窗口,该窗口打印 NULL。
但是,我发现如果我将 getter 添加到 Address
类中,我可以在 scala 模板中检索它:
添加
public String getCity() {
return city;
}
...
Address.java 结果为
John
Doe
123456
United States of America
cat
dog
cat
因此,我可以设置一个地址并将其分配给员工(它显示在我的数据库中)。此外,删除员工会正确级联并删除数据库中的地址。同样,这也适用于 OneToMany
的 Pet 类。那么为什么我需要添加 getter 来访问我的 Address
属性,而不是 Pet
呢?我的一对一关系在 Java 注释中设置不正确吗?
最佳答案
EBean 不支持通过直接属性访问进行延迟加载。
在 Java-Controller-Code 中,语句 employee.address.country
被增强为 employee.getAddress().getCountry()
之类的内容。唉,这在 Scala 代码中没有完成,特别是在模板中。
employee.pets(1).petString
被转换为 employee.pets.get(1).petString
,这对于 EBean 来说就足够了延迟加载,因为涉及到一个EBean LazyList。
请不要再坚持使用 getter/setter!表演!人们认为你应该在 Controller 中知道你需要什么数据并在查询时获取它:
public static Employee get(Long id) {
return find.fetch("address").where().idEq(id).findUnique();
}
关于java - 在 Play Framework 2.0.1 中访问 scala 模板内子实体的属性时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10760239/