Мой код в настоящее время выглядит следующим образом:
public List<DeviceOrganizationMetadataHolder> getChildrenByParentId(List<String> parentIds) throws DeviceOrganizationDAOException {
List<DeviceOrganizationMetadataHolder> children = new ArrayList<>();
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
DeviceOrganizationMetadataHolder deviceMetadataHolder;
String[] data = parentIds.toArray(new String[parentIds.size()]);
try {
conn = this.getConnection();
String sql = "SELECT * FROM DEVICE_ORGANIZATION_MAP WHERE DEVICE_PARENT IN (?)";
stmt = conn.prepareStatement(sql);
data = parentIds.toArray(data);
stmt.setObject(1, data);
rs = stmt.executeQuery();
while (rs.next()) {
deviceMetadataHolder = this.loadOrganization(rs);
children.add(deviceMetadataHolder);
}
} catch (SQLException e) {
throw new DeviceOrganizationDAOException("Error occurred for device list with while retrieving children.", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
return children;
}
}
Однако, хотя в модульных тестах я пытаюсь передать массив с parentIds, возврат остается равным нулю. То, что я могу оценить из этого, является одним из следующих:
Где я ошибаюсь?
EDIT. Был аналогичный повторяющийся вопрос, который был помечен. Хотя он предложил использовать StringBuilder и цикл, я искал ответ о том, как это можно сделать более чистым способом с использованием самого запроса.
Попробуйте установить параметр в виде списка вместо массива, т.е. заменить
stmt.setObject(1, data);
с
stmt.setObject(1, Arrays.asList(data));
Догадаться.
В h2database GitHub возникла проблема, связанная с этой точной проблемой. Последующие предлагаемые изменения, и это сработало !
Код после редактирования выглядит следующим образом:
public List<DeviceOrganizationMetadataHolder> getChildrenByParentId(List<String> parentIds) throws DeviceOrganizationDAOException {
List<DeviceOrganizationMetadataHolder> children = new ArrayList<>();
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
DeviceOrganizationMetadataHolder deviceMetadataHolder;
Object[] data = parentIds.toArray();
try {
conn = this.getConnection();
String sql = "SELECT * FROM DEVICE_ORGANIZATION_MAP WHERE DEVICE_PARENT IN (SELECT * FROM TABLE(x VARCHAR = ?))";
stmt = conn.prepareStatement(sql);
stmt.setObject(1, data);
rs = stmt.executeQuery();
while (rs.next()) {
deviceMetadataHolder = this.loadOrganization(rs);
children.add(deviceMetadataHolder);
}
} catch (SQLException e) {
throw new DeviceOrganizationDAOException("Error occurred for device list with while retrieving children.", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
return children;
}
}
Как вы можете видеть, я использовал массив объектов для данных и добавил дополнительный запрос в основной запрос. Следуя инструкциям, приведенным в выпуске GitHub, к тройнику, он работал безупречно.