java - 在 Play Framework 2.0.1 中访问 scala 模板内子实体的属性时出现问题

标签 java jpa playframework playframework-2.0 mariadb

我正在 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/

相关文章:

java - 与导航主机 fragment 大小不同的 fragment

jpa - @OneToOne 单向和双向

java - EntityManager::getDelegate 返回什么?

playframework - 如何在 Play Framework 中使用 Scala 测试 Akka Actor 的规范示例

java - 使用 Java Play Framework 2.3.x 在 Controller 中上传单元测试文件

java - 有人可以找出我的代码有什么问题吗?

java - JTable - 拖放

java - Android - 蜂窝或 ICS 完全全屏

java - 单向@OneToMany 关联未通过 JPA 中的相等性测试

java - 玩 Java - 无法连接数据库 postgreSQL