private AbstractConfig getInjectableAncestor(final PropertyPath propertyPath) {

        PropertyPath curPropertyPath = propertyPath;
        AbstractConfig ancestorConfig = null;

        while (true) {

            PropertyPath parentPath = curPropertyPath.getParent()
                    .orElseThrow(() -> new RuntimeException(LogUtil.message(
                            "Path {} has no parent", propertyPath)));

            final PropertyPath finalCurPropertyPath = curPropertyPath;
            final PropertyUtil.Prop prop = configMapper.getProp(curPropertyPath)
                    .orElseThrow(() ->
                            new RuntimeException(LogUtil.message("No prop object exists for {}",
                                    finalCurPropertyPath)));
            ancestorConfig = (AbstractConfig) prop.getParentObject();

            if (!ancestorConfig.getClass().isAnnotationPresent(NotInjectableConfig.class)) {
                break;
            }

            curPropertyPath = parentPath;
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("returning injectable ancestor {} for path {}",
                    ancestorConfig.getClass().getSimpleName(), propertyPath);
        }

        return ancestorConfig;
    }
@param id The DB primary key for the prop
@return A {@link ConfigProperty} if it exists in the DB, i.e. it has a db override value.
This means a valid prop can return an empty if the prop only has a default/yaml value.
stroom-config/stroom-config-global-impl/src/main/java/stroom/config/global/impl/GlobalConfigService.java