I'm facing big performance issues in a large collection of entities containing an @Any association.
The only way i found to improve load time is to execute a SQL query to collect ids of one of the associated type (but could do for each different type of the Any association), then load those associated entities by batch of 200 with a criteria.
Hibernate will then populate the cache with those entities so when fetching the collection, the associations are resolved directly from the cache instead of executing a SELECT for each. Working this way, the load time is divided by 3 but still remains at 14 seconds for the full load.
Is there a better way to improve the performance?
Note : The data model cannot be changed.
Model : The parent entity has a collection of administrators (up to 8k administrator). Those administrators hold the @Any association (type A,B,C).
Code:
public class Administrator {
some other stuffs...
@Any(metaColumn=@Column(name="TYPE"), optional = false, fetch=FetchType.EAGER)
@AnyMetaDef(idType="long", metaType="string", metaValues= {
@MetaValue(targetEntity=A.class, value="A"),
@MetaValue(targetEntity=B.class, value="B"),
@MetaValue(targetEntity=C.class, value="C")
})
@JoinColumn(name="NUM")
private RelationTypeIdentifier<Long> relation;
}
Code to preload the C entities which is the most common type of the Any association.
Code:
SQLQuery sqlQuery = getSession().createSQLQuery("select NUM as cId from SOMETABLE WHERE PARENTID = :id and TYPE = 'C'");
sqlQuery.setParameter("id", id);
sqlQuery.addScalar("cId", new LongType());
List<Long> cIds = sqlQuery.list();
List<C> result = new ArrayList<C>();
if (cIds.size() == 0) {
return result;
}
int batchSize = 200;
int to = (cIds.size() < batchSize) ? cIds.size() : batchSize;
int from = 0;
while (cIds.size() >= to) {
List<Long> subList = cIds.subList(from, to);
cDao.findByIds(subList.toArray(new Long[subList.size()]));
from += batchSize;
to += batchSize;
}
return result;
Relying on the cache (on which you don't have much control) is certainly not the best solution so i hope someone has a better option.
I'm using hibernate 4.3.
Thank you.