-
Notifications
You must be signed in to change notification settings - Fork 30
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
subset of entity attributes - Find methods #921
base: main
Are you sure you want to change the base?
subset of entity attributes - Find methods #921
Conversation
Signed-off-by: Nathan Rauh <[email protected]>
This approach looks basically OK to me, though I have a couple of comments. The first is that we need a way to specify the entity type when not using @Repository
public interface Cars {
record ModelInfo(String model,
String manufacturer,
int designYear) {}
@Find(Car.class)
@Project({_Car.MODEL, _Car.MAKE, _Car.YEAR})
Optional<ModelInfo> getModelInfo(String vin);
} The second comment is that I would like the option of putting @Repository
public interface Cars {
record ModelInfo(@Project(_Car.MODEL) String model,
@Project(_Car.MAKE) String manufacturer,
@Project(_Car.YEAR) int designYear) {}
@Find(Car.class)
Optional<ModelInfo> getModelInfo(String vin);
} |
i.e. I want to cut a very wide berth around horrible stuff like: @Find(from = Car.class, value = {_Car.MODEL, _Car.MAKE, _Car.YEAR})
Optional<ModelInfo> getModelInfo(String vin); Let's not box ourselves into something like that. |
That's a good idea. Having the value of
That's a nice improvement as well. This allows for more concise code because it isolates specifying the entity attribute names to a single place (the record) rather than each repository method where it is returned. Additionally, for records where all of the component names match except one, it could allow overriding only that one.
Totally agree. We should never add multiple fields to I'll get the PR updated. |
That would be fine, but I usually try to avoid "select" just because selection is really the job of the |
Once we can archive it using JPQL, do we need a duplicate version to find the annotation? Using JPQL is:
Once it is a subset, we could use a similar structure: @Repository
public interface Cars {
record ModelInfo(String model,
String manufacturer,
int designYear) {}
@Query("select new ModelInfo(model, manufacturer, year) from Car")
Optional<ModelInfo> getModelInfo(String vin);
} |
@otaviojava I think it's nice to be able to have both. @Find(Car.class)
@Project({_Car.MODEL, _Car.MAKE, _Car.YEAR})
Optional<ModelInfo> getModelInfo(String vin); vs @Query("select model, make, year from Car where vin = ?1")
Optional<ModelInfo> getModelInfo(String vin); And: @Find(Book.class)
@Project(_Book.Title)
List<String> getModelInfo(Restriction<Book> restriction, Order<Book> order); vs @Query("select title from Book")
List<String> getModelInfo(Restriction<Book> restriction, Order<Book> order); I agree that in these cases the JDQL versions look slightly cleaner, but the |
…ames to a separate annotation
PR and description are updated to split out the entity attribute names and use the Find value for the entity type instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks very reasonable. Left minor comments.
@@ -26,11 +26,25 @@ | |||
|
|||
|
|||
/** | |||
* <p>Annotates a repository method returning entities as a parameter-based automatic query method.</p> | |||
* <p>Annotates a repository method to be a parameter-based automatic query method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick, but I find "Annotates X to be Y" really clumsy English.
It's fine to write "Declares X to be Y", but I think "Annotates X as Y" was also perfectly OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like I rewrote that sentence when switching around two parts of it. I'll get that corrected back to "as" instead of "to be"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected in d93b48e along with removal of an extra "a" that I spotted in a different section that I had updated.
Co-authored-by: Gavin King <[email protected]>
Co-authored-by: Gavin King <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional comments.
Thanks- I wasn't sure what value to use - void.class is fine. Co-authored-by: Gavin King <[email protected]>
Co-authored-by: Gavin King <[email protected]>
Co-authored-by: Gavin King <[email protected]>
* int year) {} | ||
* | ||
* @Find | ||
* Optional<ModelInfo> getModelInfo(@By("vin") String vehicleIdNum); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I enjoy the @gavinking approach on this find one:
@Find(Car.class)
@Project({_Car.MODEL, _Car.MAKE, _Car.YEAR})
Optional<ModelInfo> getModelInfo(String vin);
Thus, I centralized the "builder" into a single place.
Plus, I can use a regular class instead of record, for example.
Co-authored-by: Kyle Aure <[email protected]>
* <li>a Java record type representing a subset of entity attributes returned | ||
* by the query. The names of the record components and entity attributes | ||
* must match, or the entity attribute names must be specified by the | ||
* {@link Select} annotation.</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also use a regular class here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also use a regular class here?
With a little bit of added complexity, this approach could certainly be extended to include non-record classes as well. However, I would propose that in this PR we stick with record only to start out with, get that working, and then separately consider if we want to add in non-record classes. Would that be okay with you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Nathan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Baby-steps.
I like this approach.
This PR contains some of the work for #539
It covers returning one or more entity attributes rather than the entire entity when using the
Find
annotation.(A separate PR will be needed to cover selecting multiple entity attributes in JDQL and corresponding update to
@Query
methods to allow a record return type there).This PR will enable users to write code like:
and
or for the case where the record component names don't match the entity attribute names,
or an alternative way of doing the above by placing the annotation onto the record component(s) instead (which is convenient if you have control over the definition of the record and it is used by multiple repository methods),