class CategoricalAttributeDao extends NamedParameterJdbcDaoSupport {

    @Transactional(propagation = Propagation.MANDATORY)
    public boolean insertAttributesValues(final List<CategoricalAttribute> dict) {
        final MapSqlParameterSource[] values = dict.stream()
            .filter(attribute -> Objects.nonNull(attribute.getKey()))
            .flatMap(entry -> CollectionUtils.emptyIfNull(entry.getValues())
                .stream()
                .filter(value -> Objects.nonNull(value.getValue()))
                .map(value -> AttributeValueParameters.getValueParameters(entry.getKey(), value.getValue())))
            .toArray(MapSqlParameterSource[]::new);
        if (values.length == 0) {
            return false;
        }
        final boolean valuesChanges =
            rowsChanged(getNamedParameterJdbcTemplate().batchUpdate(insertAttributeValueQuery, values));
        final Map<Pair<String, String>, Long> pairsIds = loadAll(false).stream()
            .flatMap(attribute -> CollectionUtils.emptyIfNull(attribute.getValues()).stream())
            .collect(Collectors.toMap(value -> Pair.of(value.getKey(), value.getValue()),
                                      CategoricalAttributeValue::getId));
        final MapSqlParameterSource[] links = dict.stream()
            .flatMap(entry -> CollectionUtils.emptyIfNull(entry.getValues())
                .stream()
                .peek(attributeValue -> attributeValue.setKey(entry.getKey())))
            .flatMap(attributeValue -> CollectionUtils.emptyIfNull(attributeValue.getLinks())
                .stream()
                .map(link -> getLinkParameters(pairsIds, attributeValue, link)))
            .toArray(MapSqlParameterSource[]::new);
        final boolean linksChanges =
            links.length > 0
            && rowsChanged(getNamedParameterJdbcTemplate().batchUpdate(insertAttributeValueLinkQuery, links));
        return valuesChanges || linksChanges;
    }

}