Hibernate ResultTransformer和gwt requestfactory

时间:2016-05-05 07:30:02

标签: hibernate gwt requestfactory

我创建了自定义结果转换器,它扩展了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;

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

1 个答案:

答案 0 :(得分:0)

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

我认为您的问题是您错过了@OneToOne媒体资源上的DataRow dataGrid注释:

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