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