首页 文章

JPA / Hibernate Join和Fetch单列

提问于
浏览
5

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

  • 员工(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实体时,我只需要将部门名称作为员工实体的一部分,而不需要部门表中的任何其他部分 .

  • 如何获取部门 . 只列名称列,而不是员工实体中的整个部门行(需要避免对部门制作的大型集合进行急切的提取)?如果是这样,我应该使用什么注释?

  • 如何在这种情况下处理级联?

2 回答

  • 7

    最好的选择是使集合延迟加载,然后将需要集合的查询更改为急切加载(使用join fetch) . 如果您有充分的理由不这样做,那么您可以尝试以下变通方法 .

    您可以使用投影查询 . 这将导致每个结果的[employee,name]数组 .

    select employee, employee.dept.name from Employee employee
    

    您可以使用@Formula将Employee表中的属性映射到Department表中的列(请注意,此解决方案是特定于Hibernate的)

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

    另一种选择是创建一个没有集合的新类DeptLite . 将其映射为只读 - @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  {
    
    }
    
  • 0

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

    • 使用lazy property fetching,并在模型中注释每次检索实体时不希望加载的属性 .

    • 使用Hibernate Projections并限制在每个Query中为每个属性添加PropertyProjection所需的属性 . 像这样的东西:

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

    希望这有帮助 .

相关问题