关于持久关系元素的问题

时间:2011-09-21 05:31:09

标签: hibernate jsf-2 jpa-2.0

我通常会看到使用JPA在网络上持久化的实体示例,但它只涉及一个实体。但如果涉及到关系,我无法理解。

现在举例说明,教授与部门之间有多对一的映射。

@Entity
public class Professor {
    @ManyToOne
    @JoinColumn(name="DEPT_ID")
    private Department department;
}
@Entity
public class Department {
    //normal getters and setters
    private int id;
    private String name;
}

现在,在我的JSF页面中..我通常在表单元素之间添加映射 和我的托管豆 在添加操作期间,在Web UI中,您通常会显示一个下拉框的部门 在增加新教授时。

<h:inputText value="#{myBean.currentProf.name}"/>
.
. /* other mappings here */
.
<h:selectOneMenu value="#{myBean.currentProf.department.name}>
    <f:selectItems value="#{myBean.allDepartments}"/>
</h:selectOneMenu>
<h:commandButton value="Add" actionListener="#{myBean.handleSave}" />

现在,我的问题是:是否需要首先让部门将其设置为当前部分 教授财产在坚持之前? 因为在我的情况下,我已经设置了部门名称,但没有设置部门ID ..

@ManagedBean
public class MyBean{
    public Professor currentProf;
    public BusinessService service;
    public String handleSave(){
        Department dept = service.findDepartment(currentProf.getDepartment().getName());
        currentProf.setDepartment(dept);
        service.createProfessor(currentProf);
    }
    public List<SelectItem> getAllDepartments(){
        return service.getAllDepartments();
    }
}

为了清楚起见,我只是在这里展示我的商业服务。

public class BusinessService {
  protected EntityManager em;

  public Professor createProfessor(Professor prof) {
    em.persist(prof);
    return prof;
  }
}

网上的许多例子都显示了这样的粗略例子:

Department dept = new Department();
dept.setId(1);
dept.setName("Finance");
Prof newProf = new Professor();
newProf.setDepartment(dept);
service.createProfessor(newProf);

但我认为这不是数据在Web应用程序中的呈现和收集方式。

1 个答案:

答案 0 :(得分:1)

您需要一个已加载的Department实体对象(或对其代理的引用),以便能够将其链接到教授。只是拥有部门名称不会为您提供实体对象的引用。

Hibernate documentation, Chapter 3: 3.3. Loading an object

中查看此引用

您可以使用以下命令加载对象状态:

dept = em.find(Department.class, deptId);

或只是获取它的引用:

dept = em.getReference(Department.class, deptId);  // no db hit

但是,如果要将其链接到教授,则需要检索Department对象(或其代理引用)。 Hibernate管理整个对象状态,它与其他实体的链接,因此不可能只使用名​​称将教授与部门联系起来。

如果您没有id,只有部门的名称,那么您需要像在代码中那样进行(通过名称查询Department)。