无法在Play Framework 2.0.1中的scala模板中访问子实体的属性

时间:2012-05-25 19:22:16

标签: java jpa playframework playframework-2.0 mariadb

我正在Play Framework 2.0.1中探索JPA和Ebean来研究在本地关系数据库中生成的内容。在我的测试中,我使用的是MariaDB,一个MySQL的分支。

到目前为止,我已经能够使用模型中的JPA注释在数据库中成功生成表。我想确保我学会了如何将OneToOne关系设置为另一个权限,以及OneToMany设置为另一个实体。

OneToOne:EmployeeAddress

OneToMany:EmployeePet(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)

控制器

Application.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));
    }
}

模型

Employee.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);
}

Address.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渲染上面的视图,我会在浏览器中显示以下内容:

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注释中没有正确设置?

1 个答案:

答案 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();
}