I created custom result transformer which extends BasicTransformerAdapter. In transformTuple method I create new object of 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;
}
Everything works fine. There is created list of RegistryRow objects. On client side there is RegistryRowProxy which looks like this:
@ProxyFor(value = RegistryRow.class, locator = LongEntityLocator.class)
public interface RegistryRowProxy extends EntityProxy, BeanModelTag {
Long getId();
DataRowProxy getGridRow();
Date getCreateDate();
RegistryProxy getRegistry();
Long getDataId();
}
It is used in gwt RequestFactory which calls list service.
getRequestFactory().registryRow().list(registry.getCode(), paramsId).with("gridRow").fire(receiver);
It returns data, everything is fine, but when I turn on show_sql it is doing additional selects to database. Queries like that:
select "all_columns" from RegistryRow where id = ?;
select "all_columns" from DataRow where id = ?;
These queries are done as many times as there is rows in list. I don't know how to get rid off these additional queries which have influence on perfomance. Do you know why there are additional queries to database? (I add that in entity there are variables that looks like this:
@JoinColumn(name = "T_DATA_ROWS_ID")
@NotNull
private DataRow gridRow;
but not all of them)
Update 1: Annotation look like this exactly:
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "T_DATA_ROWS_ID")
@NotNull
private DataRow gridRow;
And still it is doing queries for each row.
You are telling RequestFactory to fetch a
RegistryRowProxyand also retreive itsgridRowsubproperty (by usingwith("gridRow")).So on your backend
RequestFactorywill internally call yourgetGridRowgetter and this will cause Hibernate to (lazy) load thegridRowrelationship.To avoid the sub queries you need to tell Hibernate to eagerly load the relationship.
JPA should do this by default for
@OneToOneand@ManyToOnerelationships.I assume your problem is that you are missing the
@OneToOneannotation on yourDataRow dataGridproperty: