Skip to content

#220 - Introduce R2dbcEntityTemplate #287

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

Closed
wants to merge 7 commits into from
Closed

#220 - Introduce R2dbcEntityTemplate #287

wants to merge 7 commits into from

Conversation

mp911de
Copy link
Member

@mp911de mp911de commented Jan 24, 2020

We now provide an R2dbcEntityTemplate that allows entity-centric interaction. Entities can be loaded, inserted, updated and deleted. Additional Query and Update methods allow fine-grained changes to entities. It features a fluent API that is similar to DatabaseClient.

The main difference is that DatabaseClient is intended for simple mapped objects while R2dbcEntityTemplate has an entity-centric focus that could expand into the usage with aggregate roots.

R2dbcEntityTemplate template = new R2dbcEntityTemplate(databaseClient);

Mono<Person> saved = template.insert(new Person(…));

Mono<Integer> affectedRows = template.update(Query.query(Criteria.where("name").is("Walter")), Update.update("name", "Heisenberg"), Person.class);

Mono<Person> loaded = template.select(Person.class)
		.from("another_table)
		.as(PersonProjection.class)
		.matching(query(where("name").is("Walter")).limit(10).offset(20))
		.first();

Open issues:

Copy link
Contributor

@schauder schauder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't seem to be able to rebase this onto master due to the introduction of SqlIdentifier.
One ends up with SqlIdentifier on one side (SelectSpec) and expecting String values on the other side (Table and Column). I'm not sure where you want to make the conversion.

Do you mind rebasing this?

@mp911de
Copy link
Member Author

mp911de commented Feb 11, 2020

This PR depends on spring-projects/spring-data-relational#187. Otherwise, we would be required to do the rebase twice.

We now provide a Template API that exposes entity-centric methods. It complements DatabaseClient's simple object mapper methods.
Use limit/offset instead of Page and accept Expression objects to declare a select list. Use SqlIdentifier in Update, Query, Criteria and fluent API.
Formatting.
Fix warnings.
JavaDoc.
Copy link
Contributor

@schauder schauder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple of complains but nothing serious.
Let's discuss in Slack.

* @return the mapped {@link Expression}.
* @since 1.1
*/
public Expression getMappedObject(Expression expression, @Nullable RelationalPersistentEntity<?> entity) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this method is quite complex I'd love to have some unit tests.
Cases that should be covered IMHO:

  • entity =/!= null
  • column w/wo alias
  • demonstrating what the column-> field+table -> column roundtrip does.
  • SimpleFunction w/wo recursion
  • Aliased or not
  • Error case.


this.entity = entity;
this.entityOperations = entityOperations;
this.idProperty = Lazy.of(() -> converter //
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Lazy worth it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lazy init was required for deferred interaction with the mapping context.

Column column = (Column) expression;
Field field = createPropertyField(entity, column.getName());
Table table = column.getTable();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table might be null which would cause a NPE.
I can't tell if this prevented by construction, but an assert statement might be a good idea.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the NPE originates from @Nullable on Column.getTable. In Spring Data Relational, we made the Table mandatory, so we should fix the nullability annotations there.

@@ -212,17 +219,49 @@ public static SelectSpec create(String table) {
* @since 1.1
*/
public static SelectSpec create(SqlIdentifier table) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StatementMapper contains lots of public stuff although the class it self is package private.
Is that intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class is public as it is declared within an interface.

Reverted removal of null check that is marked as superfluous and adjusted nullability annotations instead.
@mp911de mp911de added this to the 1.1 M3 (Neumann) milestone Feb 12, 2020
mp911de added a commit that referenced this pull request Feb 12, 2020
We now provide a Template API that exposes entity-centric methods. It complements DatabaseClient's simple object mapper methods.

Original pull request: #287.
mp911de added a commit that referenced this pull request Feb 12, 2020
mp911de added a commit that referenced this pull request Feb 12, 2020
mp911de added a commit that referenced this pull request Feb 12, 2020
Use limit/offset instead of Page and accept Expression objects to declare a select list. Use SqlIdentifier in Update, Query, Criteria and fluent API.

Original pull request: #287.
mp911de pushed a commit that referenced this pull request Feb 12, 2020
Formatting.
Fix warnings.
JavaDoc.
Adjusted nullability annotations.

Original pull request: #287.
@mp911de
Copy link
Member Author

mp911de commented Feb 12, 2020

That's merged and polished now.

@mp911de mp911de closed this Feb 12, 2020
@mp911de mp911de deleted the issue/gh-220 branch February 12, 2020 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants