spring-projects / spring-projects/spring-data-keyvalue

`KeyValueTemplate` assumes a map only and tries to assign ID [DATAKV-127]

Open
#106 0 comments 0 reactions 1 assignee View on GitHub

@christophstrobl is already working on this.

Since Dec 31, 2020.

type: bug
Dominant language
Java
Stars
157
Forks
85
PR merge metrics
No merged PRs in 30d

Description

Wallace Wadge opened DATAKV-127 and commented

Apologies for the length of this post but before I explain my issue, a little discussion is in order (I think this would be a great example project actually). I like Spring Data Rest, but I don't want to expose my DB objects as my api to allow me to modify my DB without affecting my api. My DB code also lives in a separate isolated module.

I have 2 modules, a web front-end and a core; so for eg I have a Client class for my DB and ApiClient for my api. Now Spring Data KeyValue allows me to treat a map as a repository -- Great! So on web module I define my repositories + API entities and on backend I have completely different repositories, and because I have a common interface my backend mapping code is very simple, for eg:

class Foo implements KeyValueAdapter { ....
    @Override
    public boolean contains(Serializable id, Serializable keyspace) {
        boolean result = false;
        try {
            Repository repo = getRepositoryFor(keyspace.toString());

            Class<?> modelClass = apiToModelClass(keyspace); // just a naming convention

           Path<Number> idPath = path(Number.class, path(modelClass, (String)keyspace), "id");
            Predicate mainPredicate = predicate(Ops.EQ, idPath, Expressions.constant(id));

            result = ((QueryDslPredicateExecutor)repo).exists(allOf(mainPredicate, securityContextPredicate(modelClass)));
        } catch (ClassNotFoundException e) {
            log.error("Unable to invoke repo invoker for contains", e);
        }

        return result;
    }

I even map querydsl predicates between the two worlds which is very nice too, everything based on my single Api->DB model mapper (orika in my case).

Now for the problem:

KeyValueTemplate assumes I will always need to generate an ID to store in some map so IdentifierGenerator is hard-coded to DefaultIdentifierGenerator.INSTANCE; but in my case I want to send null to the other side because it will be filled later on by the db layer. Can you please:

  • Allow us to override KeyValueTemplate identifierGenerator property
  • Remove the assert in insert(...)
  • Pass more meta-data/call an alternate adapter method since both insert and update call the same .put(..) method

No further details from DATAKV-127

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.