【问题标题】:Hibernate ResultTransformer and gwt requestfactoryHibernate ResultTransformer 和 gwt requestfactory
【发布时间】:2016-05-06 22:52:36
【问题描述】:

我创建了扩展 BasicTransformerAdapter 的自定义结果转换器。在 transformTuple 方法中,我创建了 Entity 的新对象:

@Override
  public Object transformTuple(Object[] tuple, String[] aliases) {
    RegistryRow row = new RegistryRow();
    DataRow dataRow = new DataRow();
    Registry registry = new Registry();

    for (int i = 0; i < aliases.length; i++) {
      if ("id".equals(aliases[i])) {
        row.setId((Long) tuple[i]);
      } else if ("entityVersion".equals(aliases[i])) {
        row.setEntityVersion((Long) tuple[i]);
      } else if ("gridRowId".equals(aliases[i])) {
        dataRow.setId((Long) tuple[i]);
      } else if ("rowEntityVersion".equals(aliases[i])) {
        dataRow.setEntityVersion((Long) tuple[i]);
      } else if (tuple[i] != null && aliases[i] != null && aliases[i].startsWith("set")) {
        try {
          DataType type = DataRow.getDataType(tuple[i].getClass());
          Method m = DataRow.class.getMethod(aliases[i], type.getDataClass());
          m.invoke(dataRow, DataRow.castValue(tuple[i], type));
        } catch (Exception e) {
          LOG.error("--Error while setting dataRow data: ", e);
        }
      } else if ("registryCode".equals(aliases[i])) {
        registry.setCode((String) tuple[i]);
      } else if ("registryEntityVersion".equals(aliases[i])) {
        registry.setEntityVersion((Long) tuple[i]);
      }
    }

    row.setRegistry(registry);
    row.setGridRow(dataRow);

    return row;
  }

一切正常。已创建 RegistryRow 对象列表。 在客户端有 RegistryRowProxy,它看起来像这样:

@ProxyFor(value = RegistryRow.class, locator = LongEntityLocator.class)
public interface RegistryRowProxy extends EntityProxy, BeanModelTag {

  Long getId();

  DataRowProxy getGridRow();

  Date getCreateDate();

  RegistryProxy getRegistry();

  Long getDataId();
}

在调用列表服务的gwt RequestFactory中使用。

getRequestFactory().registryRow().list(registry.getCode(), paramsId).with("gridRow").fire(receiver);

它返回数据,一切都很好,但是当我打开 show_sql 时,它正在对数据库进行额外的选择。类似的查询:

select "all_columns" from RegistryRow where id = ?; 
select "all_columns" from DataRow where id = ?;

这些查询的执行次数与列表中的行数一样多。我不知道如何摆脱这些影响性能的额外查询。你知道为什么对数据库有额外的查询吗? (我在实体中添加了一些看起来像这样的变量:

@JoinColumn(name = "T_DATA_ROWS_ID")
  @NotNull
  private DataRow gridRow;

但不是全部)

更新 1: 注释看起来像这样:

@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)  
@JoinColumn(name = "T_DATA_ROWS_ID")  
@NotNull  
private DataRow gridRow;

它仍在对每一行进行查询。

【问题讨论】:

    标签: hibernate gwt requestfactory


    【解决方案1】:

    您告诉 RequestFactory 获取 RegistryRowProxy 并检索其 gridRow 子属性(通过使用 with("gridRow"))。
    因此,在您的后端 RequestFactory 将在内部调用您的 getGridRow getter,这将导致 Hibernate(懒惰)加载 gridRow 关系。
    为了避免子查询,您需要告诉 Hibernate 急切地加载关系。
    默认情况下,JPA 应该为 @OneToOne@ManyToOne 关系执行此操作。

    我认为您的问题是您的 DataRow dataGrid 属性上缺少 @OneToOne 注释:

    @JoinColumn(name = "T_DATA_ROWS_ID",nullable=false)
    @NotNull
    @OneToOne
    private DataRow gridRow;
    

    【讨论】:

    • 在代码中它看起来像这样:@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "T_DATA_ROWS_ID") @NotNull private DataRow gridRow;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 2011-06-25
    • 2011-09-19
    • 2011-05-26
    • 2012-04-09
    相关资源
    最近更新 更多