代码之家  ›  专栏  ›  技术社区  ›  Gazeciarz

使用休眠条件进行休眠继承(TABLE_PER_CLASS)

  •  3
  • Gazeciarz  · 技术社区  · 8 年前

    我有一个带有小部件列表的Cell。Widgets是一个抽象实体,用于存储所有未来实体(如按钮、搜索、条件等)的公共属性。请不要考虑ClassNamed接口,它对我的结果没有影响,我检查了两次。

    单元格(带小工具列表):

    @Entity
    @Table(name = "DASHBOARD_CELL")
    public class DashboardCell {
    
        private Integer id;
        private Integer rowPosition;
        private Integer columnPosition;
        private Integer columnWeight;
        private DashboardBox dashboardBox;
        private List<DashboardWidget> dashboardWidgets;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "ID")
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        @Column(name = "ROW_POSITION")
        public Integer getRowPosition() {
            return rowPosition;
        }
    
        public void setRowPosition(Integer rowPosition) {
            this.rowPosition = rowPosition;
        }
    
        @Column(name = "COLUMN_POSITION")
        public Integer getColumnPosition() {
            return columnPosition;
        }
    
        public void setColumnPosition(Integer columnPosition) {
            this.columnPosition = columnPosition;
        }
    
        @Column(name = "COLUMN_WEIGHT")
        public Integer getColumnWeight() {
            return columnWeight;
        }
    
        public void setColumnWeight(Integer columnWeight) {
            this.columnWeight = columnWeight;
        }
    
        @ManyToOne(optional = false, fetch=FetchType.LAZY)
        @JoinColumn(name="DASHBOARD_BOX_ID")
        @JsonBackReference
        public DashboardBox getDashboardBox() {
            return dashboardBox;
        }
    
        public void setDashboardBox(DashboardBox dashboardBox) {
            this.dashboardBox = dashboardBox;
        }
    
        @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "dashboardCell", fetch=FetchType.EAGER)
        @JsonManagedReference
        public List<DashboardWidget> getDashboardWidgets() {
            return dashboardWidgets;
        }
    
        public void setDashboardWidgets(List<DashboardWidget> dashboardWidgets) {
            this.dashboardWidgets = dashboardWidgets;
        }
    
    }
    

    小装置:

    @Entity
    @Table(name = "DASHBOARD_WIDGET")
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class DashboardWidget implements ClassNamed{
    
        private Integer id;
        private String title;
        private Integer backgroundColor;
        private Integer orderNumber;
        private DashboardCell dashboardCell;
        private String widgetType = getWidgetType();
    
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE)
        @Column(name = "ID")
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        @Column(name = "TITLE")
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        @Column(name = "BACKGROUND_COLOR_VALUE")
        public Integer getBackgroundColor() {
            return backgroundColor;
        }
    
        public void setBackgroundColor(Integer backgroundColor) {
            this.backgroundColor = backgroundColor;
        }
    
        @Column(name = "ORDER_NUMBER")
        public Integer getOrderNumber() {
            return orderNumber;
        }
    
        public void setOrderNumber(Integer orderNumber) {
            this.orderNumber = orderNumber;
        }
    
        @ManyToOne(optional = false)
        @JoinColumn(name = "DASHBOARD_CELL_ID")
        @JsonBackReference
        public DashboardCell getDashboardCell() {
            return dashboardCell;
        }
    
        public void setDashboardCell(DashboardCell dashboardCell) {
            this.dashboardCell = dashboardCell;
        }
    
        public String getWidgetType() {
            return getClassName();
        }
    
        public void setWidgetType(String widgetType) {
            this.widgetType = widgetType;
        }
    }
    

    标准小工具:

    @Entity
    @Table(name = "DASHBOARD_CRITERIA")
    public class DashboardCriteria extends DashboardWidget {
        private Integer value;
        private Integer maximumValue;
    
        @Column(name = "ACTUAL_VALUE")
        public Integer getValue() {
            return value;
        }
    
        public void setValue(Integer value) {
            this.value = value;
        }
    
        @Column(name = "MAX_VALUE")
        public Integer getMaximumValue() {
            return maximumValue;
        }
    
        public void setMaximumValue(Integer maximumValue) {
            this.maximumValue = maximumValue;
        }
    
        @Transient
        @Override
        public String getClassName() {
            return DashboardCriteria.class.getName();
        }
    
    }
    

    当我尝试使用以下代码查询具有小部件的所有单元格时:

    sessionFactory.getCurrentSession().createCriteria(DashboardCell.class).list();
    

    我得到了4条记录:1个细胞有4个标准,1个(同一个细胞)有4个条件,1个细胞(同一细胞)有四个标准,一个细胞(相同细胞)有四个标准。我在数据库中有一个单元格,其中包含4个DashBoardCriteria(H2数据库):

    insert into DASHBOARD_CELL (ID, ROW_POSITION, COLUMN_POSITION, COLUMN_WEIGHT, DASHBOARD_BOX_ID) values (100, 0, 0, 12, 6);
    
    insert into DASHBOARD_CRITERIA (ID, TITLE, BACKGROUND_COLOR_VALUE, ORDER_NUMBER, DASHBOARD_CELL_ID, ACTUAL_VALUE, MAX_VALUE) values (200, 'Registered', 16769408, 0, 100, 21, 30);
    insert into DASHBOARD_CRITERIA (ID, TITLE, BACKGROUND_COLOR_VALUE, ORDER_NUMBER, DASHBOARD_CELL_ID, ACTUAL_VALUE, MAX_VALUE) values (201, 'Completed', 11723766, 1, 100, 22, 30);
    insert into DASHBOARD_CRITERIA (ID, TITLE, BACKGROUND_COLOR_VALUE, ORDER_NUMBER, DASHBOARD_CELL_ID, ACTUAL_VALUE, MAX_VALUE) values (202, 'Approved', 11921353, 2, 100, 5, 30);
    insert into DASHBOARD_CRITERIA (ID, TITLE, BACKGROUND_COLOR_VALUE, ORDER_NUMBER, DASHBOARD_CELL_ID, ACTUAL_VALUE, MAX_VALUE) values (203, 'Cancelled', 16755884, 3, 100, 17, 30);
    

    我假设这个查询给出了(单元格数*小部件数)。我的问题是为什么?我认为hibernate应该自动加入孩子们,不是吗?我做错了什么事,或者可能是什么原因?

    HQL查询:

    SELECT this_.ID AS ID1_1_1_,
           this_.COLUMN_POSITION AS COLUMN_P2_1_1_,
           this_.COLUMN_WEIGHT AS COLUMN_W3_1_1_,
           this_.DASHBOARD_BOX_ID AS DASHBOAR5_1_1_,
           this_.ROW_POSITION AS ROW_POSI4_1_1_,
           dashboardw2_.DASHBOARD_CELL_ID AS DASHBOAR6_3_3_,
           dashboardw2_.ID AS ID1_3_3_,
           dashboardw2_.ID AS ID1_3_0_,
           dashboardw2_.BACKGROUND_COLOR_VALUE AS BACKGROU2_3_0_,
           dashboardw2_.DASHBOARD_CELL_ID AS DASHBOAR6_3_0_,
           dashboardw2_.ORDER_NUMBER AS ORDER_NU3_3_0_,
           dashboardw2_.TITLE AS TITLE4_3_0_,
           dashboardw2_.widgetType AS widgetTy5_3_0_,
           dashboardw2_.MAX_VALUE AS MAX_VALU1_2_0_,
           dashboardw2_.ACTUAL_VALUE AS ACTUAL_V2_2_0_,
           dashboardw2_.clazz_ AS clazz_0_
    FROM DASHBOARD_CELL this_
    LEFT OUTER JOIN
      (SELECT ID,
              BACKGROUND_COLOR_VALUE,
              ORDER_NUMBER,
              TITLE,
              widgetType,
              DASHBOARD_CELL_ID,
              MAX_VALUE,
              ACTUAL_VALUE,
              1 AS clazz_
       FROM DASHBOARD_CRITERIA) dashboardw2_ ON this_.ID=dashboardw2_.DASHBOARD_CELL_ID
    WHERE this_.DASHBOARD_BOX_ID=?
    

    我从H2移动到postgresql.我执行了查询,结果似乎是正确的-我收到了链接到一个单元格的4个小部件。可能是hibernate 5中的一个错误,我有4次相同的对象?

    1 回复  |  直到 8 年前
        1
  •  1
  •   JB Nizet    8 年前

    它按设计工作。就像在HQL/JPQL中一样,您需要使用 distinct ,在条件中,您需要

    criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);