"." +
manager.getMetaData().getName());
}
public Collection execute(JDBCCMRFieldBridge cmrField, Object pk) {
JDBCCMRFieldBridge relatedCMRField = (JDBCCMRFieldBridge) cmrField.getRelatedCMRField();
// get the read ahead cahces
ReadAheadCache readAheadCache = manager.getReadAheadCache();
ReadAheadCache relatedReadAheadCache = cmrField.getRelatedManager().getReadAheadCache();
// get the finder results associated with this context, if it exists
ReadAheadCache.EntityReadAheadInfo info = readAheadCache.getEntityReadAheadInfo(pk);
List loadKeys = info.getLoadKeys();
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// generate the sql
boolean[] preloadMask = getPreloadMask(cmrField);
String sql = getSQL(cmrField, preloadMask, loadKeys.size());
// create the statement
if (log.isDebugEnabled())
log.debug("load relation SQL: " + sql);
// get the connection
con = cmrField.getDataSource().getConnection();
ps = con.prepareStatement(sql.toString());
// Set the fetch size of the statement
if (entity.getFetchSize() > 0) {
ps.setFetchSize(entity.getFetchSize());
}
// get the load fields
JDBCCMPFieldBridge[] myKeyFields = getMyKeyFields(cmrField);
JDBCCMPFieldBridge[] relatedKeyFields = getRelatedKeyFields(cmrField);
// set the parameters
int paramIndex = 1;
for (int i = 0; i < loadKeys.size(); i++) {
Object key = loadKeys.get(i);
for (int j = 0; j < myKeyFields.length; ++j)
paramIndex = myKeyFields[j].setPrimaryKeyParameters(ps, paramIndex, key);
}
// execute statement
rs = ps.executeQuery();
// initialize the results map
Map resultsMap = new HashMap(loadKeys.size());
for (int i = 0; i < loadKeys.size(); ++i) {
resultsMap.put(loadKeys.get(i), new ArrayList());
}
// load the results
Object[] ref = new Object[1];
while (rs.next()) {
// reset the column index for this row
int index = 1;
// ref must be reset to null before each load
ref[0] = null;
// if we are loading more then one entity, load the pk from the row
Object loadedPk = pk;
if (loadKeys.size() > 1) {
// load the pk
for (int i = 0; i < myKeyFields.length; ++i) {
index = myKeyFields[i].loadPrimaryKeyResults(rs, index, ref);
if (ref[0] == null) {
break;
}
}
loadedPk = ref[0];
}
// load the fk
ref[0] = null;
for (int i = 0; i < relatedKeyFields.length; ++i) {
index = relatedKeyFields[i].loadPrimaryKeyResults(rs, index, ref);
if (ref[0] == null) {
break;
}
}
Object loadedFk = ref[0];
if (loadedFk != null) {
// add this value to the list for loadedPk
List results = (List) resultsMap.get(loadedPk);
results.add(loadedFk);
// if the related cmr field is single valued we can pre-load
// the reverse relationship
if (relatedCMRField.isSingleValued()) {
relatedReadAheadCache.addPreloadData(
loadedFk,
relatedCMRField,
Collections.singletonList(loadedPk));
}
// read the preload fields
if (preloadMask != null) {
JDBCFieldBridge[] relatedFields = cmrField.getRelatedJDBCEntity().getTableFields();
for (int i = 0; i < relatedFields.length; ++i) {
if (preloadMask[i]) {
JDBCFieldBridge field = relatedFields[i];
ref[0] = null;
// read the value and store it in the readahead cache
index = field.loadArgumentResults(rs, index, ref);
relatedReadAheadCache.addPreloadData(loadedFk, field, ref[0]);
}
}
}
}
}
// set all of the preloaded values
JDBCReadAheadMetaData readAhead = relatedCMRField.getReadAhead();
for (Iterator iter = resultsMap.keySet().iterator(); iter.hasNext(); ) {
Object key = iter.next();
// get the results for this key
List results = (List) resultsMap.get(key);