Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotation for data repositories #3

Closed
1 of 4 tasks
njr-11 opened this issue Sep 5, 2022 · 16 comments
Closed
1 of 4 tasks

Annotation for data repositories #3

njr-11 opened this issue Sep 5, 2022 · 16 comments
Labels
enhancement New feature or request
Milestone

Comments

@njr-11
Copy link
Contributor

njr-11 commented Sep 5, 2022

As a follow-on to the first issue, have an annotation by which an application identifies data repository interfaces to the container/runtime, enabling the container to supply the implementation.

Description

As a:

  • Application user/user of the configuration itself
  • API user (application developer)
  • SPI user (container or runtime developer)
  • Specification implementer

...I need to be able to:

designate a data repository interface for which I'd like the container/runtime to provide an injectable CDI bean with implementation of data access methods that I define on the interface

...which enables me to:

avoid writing boilerplate code and focus my code more clearly on the data model and its usage of data.

Make it a CDI bean-defining annotation in order to spare the user from steps to ensure the injection points within the archive are processed by CDI, so it can just work by default even if the application does not happen to use CDI for other purposes.

The annotation should be able to optionally identify the entity type upon which the data repository interface operates. Due to parameterized types, that information cannot always otherwise be inferred.

As to whether or not additional configuration might be associated with the annotation is left as a topic for separate issues.

Possible usage could be something like this:

@Repository(Product.class)
public interface Products extends DataRepository<Product, Long> {
    List<Product> findBy...
}
    @Inject
    Products products;

    ...
    List<Product> found = products.findBy...
}

This annotation's JavaDoc would be an intuitive starting point for users, so we should plan to include a good example there and have well-documented descriptions of how to form valid data repository interface methods.

@njr-11 njr-11 added the enhancement New feature or request label Sep 5, 2022
@keilw
Copy link
Member

keilw commented Sep 5, 2022

@njr-11 With "link to" you mean implement? I'd say this has a relation to #1.

@graemerocher
Copy link
Contributor

  1. @Repository makes more sense as it is well known annotation that developers already understand from the major implementations
  2. Not sure that the type targeted should be a required argument to the annotation since this can be inferred via generics. Doesn't seem like a bad idea but should be optional IMO

@keilw
Copy link
Member

keilw commented Sep 5, 2022

@graemerocher Which major implementations?
Looking at Spring Data which @otaviojava explicitly mentioned it has this "tagging interface" Repository<T,ID>, but no extra annotation by the same name, which frankly would be very bad and confusing.
So either not have an interface Repository and instead such annotation, or something else, like the one Spring has: Persistent

Annotation to generally identify persistent types, fields and parameters.

Of course Data would also work, if it works for other patterns and constructs like the Template, as well.,

I know, finding names often isn't easy, it took quite a while for Jakarta Security, but that's why "major implementations" being just one (e.g. Micronaut? ;-) is not enough here for a broad spec.

Let's collect a "representative" list of SQL and NoSQL frameworks. NoSQL Endgame compares quite a few already.

@graemerocher
Copy link
Contributor

This is incorrect Spring has for years had an annotation called @Repository which Spring Data has leveraged for years. See https://howtodoinjava.com/spring-boot/repository-annotation/

Major implementations I was referring to Micronaut and Spring and part of what I would like to see with the spec process is something that emerges that can be implemented by both of these and also is easy to understand for developers used to these frameworks.

@njr-11
Copy link
Contributor Author

njr-11 commented Sep 5, 2022

  1. @Repository makes more sense as it is well known annotation that developers already understand from the major implementations

I'd be equally happy with the name @Repository or another name that someone comes up with. I only used @Data in the example because it was short to type.

2. Not sure that the type targeted should be a required argument to the annotation since this can be inferred via generics. Doesn't seem like a bad idea but should be optional IMO

Good idea. The type could certainly be made optional when possible to infer.

@njr-11
Copy link
Contributor Author

njr-11 commented Sep 5, 2022

@njr-11 With "link to" you mean implement? I'd say this has a relation to #1.

It definitely relates to #1. I didn't intend to replace that issue, only to propose an additional aspect that would be useful/needed. And I didn't write that last section very well. I was meaning to talk about JavaDoc there, which is why I used the phrase "link to" there. That can just be ignored for now - I was getting to far ahead of things to be thinking about what might go into JavaDoc at this point.

@keilw
Copy link
Member

keilw commented Sep 5, 2022

Well then that's more the kind of place we would have under Jakarta Annotations or maybe CDI, not Spring Data as such. It is indeed more along the lines of Resource or similar annotations.
So it's certainly a valid question, whether the Repository Pattern and such annotation could be used by other specs (think of the SecurityStore in Jakarta Security or similar use cases) because then the pattern would go beyond a "RepositorySomething" interface for CRUD operations (Micronaut called it RepositoryOperations, Spring Data CrudRepository and in Jakarta NoSQL it's currently just called Repository combining the two interfaces in Spring Data)

The PanacheRepository in Hibernate ORM Panache seems more tightly coupled to Jakarta Persistence, but aside from that it also offers the repository pattern.

The question is, why are the makers of CDI fine with:

@ApplicationScoped
public class PersonRepository implements PanacheRepository<Person> {

   // put your custom logic here as instance methods

   public Person findByName(String name){
       return find("name", name).firstResult();
   }

   public List<Person> findAlive(){
       return list("status", Status.Alive);
   }

   public void deleteStefs(){
       delete("name", "Stef");
  }
}

Used:

@Inject
PersonRepository personRepository;

@GET
public long count(){
    return personRepository.count();
}

And why do others either on a framework level (Spring) or specific to Data (Micronaut) need an extra annotation?

@graemerocher
Copy link
Contributor

I can't comment for Spring. For Micronaut an annotation is needed since Micronaut is based on annotation processing which requires the presence of at least one annotation so that we can trigger the annotation processors. If no annotation is present then nothing is triggered.

If the proposal goes ahead without an annotation declaring the repository then we won't be able to implement the spec I am afraid.

@keilw
Copy link
Member

keilw commented Sep 6, 2022

Spring Data doesn't insist on using that annotation on the repository, see the official examples, but you can
And neither does Jakarta Data

If at least one annotation is required, what's wrong with @ApplicationScoped?
Spring does use it in other examples, but an example of combining template and repository shows, the @Component annotation does just fine and after all @Repository is just a specialized extension.

There's always the option of implementation specific extensions, just take @Readonly in EclipseLink, an annotation that has not made it into the JPA spec so far and gets used by EclipseLink on its own.

I'm not saying we should not have such annotation, but we should ask ourselves and at least the CDI team, whether it makes more sense here or there.
Looking at [What's the difference between @Component, @Repository & @Service annotations in Spring? it may have been put into a bad place by Spring after all, because the exception handling is totally DAO specific.

However, the Repository Pattern is not restricted to DB access, look at this example of Repository Pattern with consuming an external REST web service via HttpClient. That's why we should speak to other specs like REST or CDI to find out, if it is really just for DB here or better declared in another spec like CDI.

@m0mus
Copy link

m0mus commented Sep 6, 2022

Adding my 2 cents to this conversation.

  1. I don't see anything bad in requiring annotating your repositories with @Repository annotation. It makes build-time processing easier (or even must-have as @graemerocher mentioned above). Also it's a marker to distinguish repositories from other types of specific classes.
  2. Is CDI integration absolutely required? What if an implementation uses another injection framework? Does it make sense to decouple Jakarta Data from any injection framework?

@Emily-Jiang
Copy link
Contributor

Emily-Jiang commented Sep 6, 2022 via email

@keilw
Copy link
Member

keilw commented Sep 6, 2022

What about @m0mus' point, whether or not it even requires CDI annotations compared to "normal" ones?
Without CDI it would equally work in Jakarta Annotations.

@otaviojava
Copy link
Contributor

otaviojava commented Sep 6, 2022

I like the annotation to be @Data and the annotation to be Repository

@otaviojava
Copy link
Contributor

Hello everyone, I've created the voting session as an issue:
#6

@njr-11
Copy link
Contributor Author

njr-11 commented Sep 12, 2022

Hello everyone, I've created the voting session as an issue: #6

The voting under #6 shows a 12 to 4 preference for @Repository over the @Data. I've updated the description of this issue to reflect that.

@otaviojava
Copy link
Contributor

It looks like a close issue; thus, I'll close it.

njr-11 referenced this issue in njr-11/data Nov 10, 2022
njr-11 referenced this issue in njr-11/data Nov 22, 2022
njr-11 referenced this issue in njr-11/data Nov 22, 2022
njr-11 referenced this issue in njr-11/data Nov 29, 2022
otaviojava pushed a commit that referenced this issue Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants