You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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.
The text was updated successfully, but these errors were encountered:
So in implementing the spec, I really struggled a bit to know what to do with the dataSource in the @Repository annotation. I really didn't want to map it to the old legacy JNDI stuff.
In the end what I ended up with was this, which is I believe right for Quarkus, and almost correct for a "regular" Jakarta EE server:
@TransactionScoped@Generated("org.hibernate.processor.HibernateProcessor")
publicclassRepo_implementsRepo {
private@NonnullStatelessSessionsession;
// constructor for testingpublicRepo_(@NonnullStatelessSessionsession) {
this.session = session;
}
// resource accessor method@Overridepublic@NonnullStatelessSessionsession() {
returnsession;
}
// injection of the persistence unit@Inject@PersistenceUnit(unitName="myds")
privateEntityManagerFactorysessionFactory;
// constructor for CDI@InjectRepo_() {
}
// create a session after injection (ugh)@PostConstructprivatevoidopenSession() {
session = sessionFactory.unwrap(SessionFactory.class).openStatelessSession();
}
// clean up the session@PreDestroyprivatevoidcloseSession() {
session.close();
}
...
}
This is OK, but definitely isn't as clean as I would have preferred.
The dataSource is interpreted as a JPA persistence unit name and maps to the unitName of @PersistenceUnit.
The actual code is a bit nasty because @PersistenceUnit was defined well before CDI existed and doesn't allow constructor injection.
Now, if the persistence unit were identified by CDI qualifier annotations, I could just replace the @PersistenceUnit with the qualifiers in this generated code, or I could do even better and clean up this mess to just use constructor injection.
As a ...
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.
static
fields, so we can't put them there either.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.
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.
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.
The text was updated successfully, but these errors were encountered: