具有休眠标准的休眠继承 (TABLE_PER_CLASS)

Hibernate inheritance with hibernate criteria (TABLE_PER_CLASS)

我有一个包含小部件列表的单元格。 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);

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

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 个链接到一个单元格的小部件..可能是休眠 5 中的一个错误,我有多个相同的 objects 4次?

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

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);