我正在Play Framework 2.0.1中探索JPA和Ebean来研究在本地关系数据库中生成的内容。在我的测试中,我使用的是MariaDB,一个MySQL的分支。
到目前为止,我已经能够使用模型中的JPA注释在数据库中成功生成表。我想确保我学会了如何将OneToOne关系设置为另一个权限,以及OneToMany设置为另一个实体。
OneToOne:Employee
有Address
OneToMany:Employee
有Pet
(s)
我设置了一个小应用程序,允许我快速填充表格,显示一些信息,并从表格中删除行。以下是希望查看我的设置的人的代码:
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)
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));
}
}
@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);
}
@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;
}
@Entity
public class Pet extends Model {
@Id
public Long pet_id;
public String petString;
}
@(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渲染上面的视图,我会在浏览器中显示以下内容:
John
Doe
123456
cat
dog
cat
请注意,不会显示地址的国家/地区。我也尝试在控制器中访问它并将其打印到命令窗口,该窗口打印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注释中没有正确设置?
答案 0 :(得分:1)
EBean 不支持使用直接属性访问的延迟加载。
在Java-Controller-Code中,语句employee.address.country
被增强为类似employee.getAddress().getCountry()
的内容。唉,这在Scala代码中完成不,特别是在模板中没有。
employee.pets(1).petString
被转换为employee.pets.get(1).petString
,这足以使EBean延迟加载,因为涉及EBean LazyList。
请不要再忍住吸气鬼/安装者!表演!人们认为你应该在控制器中知道你需要什么数据并在查询时获取它:
public static Employee get(Long id) {
return find.fetch("address").where().idEq(id).findUnique();
}