jakartaee / jakartaee/data

[Use Case]: use CDI qualifier annotations to select a data source

Open
#476 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Java
Stars
150
Forks
37
Avg merge
4d 4h
Merged PRs (30d)
34

Description

### As a ...

- [ ] Application user/user of the configuration itself
- [X] API user (application developer)
- [ ] SPI user (container or runtime developer)
- [ ] Specification implementer

### I need to be able to ...

specify the data source that backs a repository via CDI qualifier annotations.

### Which enables me to ...

avoid the use of stringly-typed names.

### Additional information

Currently, a datasource, persistence unit, etc, that backs a repository implementation must be specified using `@Repository(dataStore=".....")` which works, but is not properly integrated with the CDI bean manager.

It would be nice to be able to disambiguate the data source or persistence unit or whatever via the placement of CDI qualifier annotations on the repository interface. Unfortunately, there's no obvious _completely_ natural place to put them.

- Interfaces don't have constructors, so we can't put them on a constructor parameter.
- Interfaces don't have non-`static` fields, so we can't put them there either.
- A qualifier annotation on the interface itself is most naturally interpreted as specifying the CDI qualifiers of the _repository itself_, not of the datasource backing it.

So, the only options I can really imagine are the following.

Use of method injection
==================

The data source could be viewed as being injected via a method, which is a concept which does already exist in CDI.

```java
@Repository
interface DocumentRepo {

@Inject
void init(@DocumentDatabase DataSource ds);

...

}
```

The problem with this is that it exposes to clients the possibility of manipulating the state of the repository. (And interface methods are always `public`.)

So this is no good. I would say we definitely don't want to do it this way.

Annotate the resource access method
============================

I actually think this option is pretty good and natural. Probably most repositories are going to want to have a resource accessor method, and so that's a place we can put these annotations.

```java
@Repository
interface DocumentRepo {

@DocumentDatabase
DataSource datasource();

...

}
```

It's true that this is a non-standard place to place qualifier annotations in the sense that it's not contemplated by the CDI spec, but to me that's completely fine. The repository implementation can easily obtain the qualifiers from this method declaration and use them to look up the data source at runtime. Alternatively, an annotation processor can copy them onto an injection point of the repository implementation.

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.

Research direction

Start by reviewing how @Repository currently selects a dataStore and how CDI qualifier annotations could be discovered from repository interfaces. Compare the proposed method-injection and resource-accessor approaches, then define and document a consistent qualifier behavior with coverage for the selected approach.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.