Hibernate继承与hibernate标准(TABLE_PER_CLASS)

时间:2016-06-04 19:59:36

标签: java hibernate hibernate-criteria

我有一个包含小部件列表的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;
    }
}

CriteriaWidget:

@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个标准,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次多个相同的对象? / p>

1 个答案:

答案 0 :(得分:1)

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

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);