5

我是 JPA/Hibernate 的新手。假设我有这两个表:

  • Employee (Id, Name, DeptId, ..) // DeptId 是外键。
  • Department (Id, DeptName, ..) // 部门单独持久化

和如下实体:

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String name;
    private long salary;

    @OneToOne(cascade = {CascadeType.PERSIST})
    @JoinColumn(name="DEPT_ID") 
    private Dept dept;
    ...
    }

@Entity
public class Dept {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String name;
    ...
    **other huge collections with eager fetch ***
    }

在我的应用程序 DAO 中,每当我访问 Employee 实体时,我只需要将部门名称作为员工实体的一部分,而不需要从部门表中获取其他任何内容。

  1. 如何获取部门。仅名称列,而不是员工实体中的整个部门行(需要避免急切地获取部门收集的大量数据)?如果是这样,我应该使用什么注释?
  2. 在这种情况下如何处理级联?
4

2 回答 2

9

The best option is to make the collection lazy loaded and then change the queries where the collection is needed to eager load (using join fetch). If you have a very good reason not to do that then you can try the following workarounds.

You can use a projection query. This will result in a [employee,name] array for each result.

select employee, employee.dept.name from Employee employee

You can use @Formula to map an attribute in Employee table to a column in Department table (note that this solution is Hibernate-specific)

class Employee {

   @Formula("(select deptName from Department where Department.id = DEPT_ID)"
   String deptName;

} 

The other option is to create an new class DeptLite which doesn't have the collection. Map it as readonly - @org.hibernate.annotations.Entity(mutable=false).

@Entity
public class Employee {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String name;
    private long salary;

    @OneToOne(cascade = {CascadeType.PERSIST})
    @JoinColumn(name="DEPT_ID") 
    private Dept dept;

    @OneToOne(updatable=false,insertable=false)
    @JoinColumn(name="DEPT_ID") 
    private DeptLite deptLite;

    ...
}

@Entity
@org.hibernate.annotations.Entity(mutable=false)
class DeptLite  {

}
于 2012-09-07T06:07:49.097 回答
0

如果您想要限制实体中加载的属性,我认为有两种方法可以实现:

  1. 使用惰性属性获取,并在模型中注释您不想在每次检索实体时加载的属性。

  2. 使用 Hibernate Projections 并限制您在每个查询中需要哪些属性,为每个属性添加一个 PropertyProjection。像这样的东西:

    Projections.projectionList().add(Projections.property("prop1")).add(Projections.property("prop2")).. 
    

希望这有帮助。

于 2012-09-07T06:44:40.767 回答