Skip to content

DATAJDBC-326 - Support conversion of backreferences. #118

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

Conversation

schauder
Copy link
Contributor

Ids used as backreferences now get properly converted.

Introduced ParentKeys.
ParentKeys hold information about data that needs to be considered for inserts or updates but is not part of the entity.
Appart from column names and values they also hold information about the desired JdbcType in order to facilitate conversions.
This replaces the Map handed around in the past.

/**
* @author Jens Schauder
*/
public class ParentKeys {
Copy link
Member

Choose a reason for hiding this comment

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

Let's turn this type into a proper value/domain type such as Identifier as in entity/aggregate identifier that encapsulates simple and composite (primary) key parts and move the type into data.relational.domain.

This seems a decent addition that could be reused in Spring Data R2DBC.

*
* @param additionalParameters
*/
@Deprecated
Copy link
Member

Choose a reason for hiding this comment

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

We should not introduce @Deprecated methods in newly introduced code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

/**
* Creates ParentKeys with backreference for the given path and value of the parents id.
*/
static ParentKeys forBackReferences(PersistentPropertyPath<RelationalPersistentProperty> path, @Nullable Object value) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's move these factory/construction method to BasicJdbcConverter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

String name;
Object value;
Class<?> targetType;
}
Copy link
Member

Choose a reason for hiding this comment

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

Proposal: We might want to consider a ParentKeyConsumer (interface ParentKeyConsumer{ void accept(String,Object,Class<?>); }) to expose a forEach(ParentKeyConsumer) method to consume the object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I created a forEach method but no separate consumer interface since I currently don't see a benefit of the generic Consumer<ParentKey>.

@schauder
Copy link
Contributor Author

@mp911de the second round of review, please.

Copy link
Member

@mp911de mp911de left a comment

Choose a reason for hiding this comment

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

This really goes in a decent direction, like it a lot. Added a few comments.

this.keys = Collections.unmodifiableList(keys);
}

public Identifier withQualifier(PersistentPropertyPath<RelationalPersistentProperty> path, Object value) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's move the method to a place where it is called as we should not have references to PersistentPropertyPath in the domain model.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would put the method in the DefaultJdbcInterpreter.

This doesn't feel right to me for two reasons:

  1. We now have factory methods in one place and add-functionality in a different place.
  2. One keeps passing Identifier instances around.

I wonder if a JdbcIdentifierBuilder in the jdbc.core.convert package would be a better approach.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

If we don't have a good place to build Identifier, then let's create one. JdbcIdentifierBuilder sounds good.

* @since 1.1
*/
@Value
public static class SingleIdentifierValue {
Copy link
Member

Choose a reason for hiding this comment

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

How about renaming it to Qualifier? This would align nicely with the withQualifier(…) method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it isn't just used for qualifiers, but also for backreferences and in the future simply for parts of an identifier.

While I'm not proud of the current name I don't think "qualifier" would be an improvement.


private final List<SingleIdentifierValue> keys;

public Identifier(List<SingleIdentifierValue> keys) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this one private and introduce rather factory methods (empty(), from(Map)).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So you didn't want to move fromNamedValues out to BasicJdbcConverter?


@Deprecated
public Map<String, Object> getParametersByName() {
return new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

Is this intended to return an empty map?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops.

}

public Collection<SingleIdentifierValue> getParameters() {
return keys;
Copy link
Member

Choose a reason for hiding this comment

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

Returning the collection directly breaks immutability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

keys is already an unmodifiableList so the only breakage of immutability I see is when contained values aren't immutable and I don't think we can do anything about that, can we?

* @author Jens Schauder
* @since 1.1
*/
public class Identifier {
Copy link
Member

Choose a reason for hiding this comment

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

Let's make the type final to encapsulate it.


Identifier identifier = BasicJdbcConverter //
.forBackReferences(path, "parent-eins") //
.withQualifier(path, "list-index-eins");
Copy link
Member

Choose a reason for hiding this comment

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

👍

public static Identifier fromNamedValues(Map<String, Object> additionalParameters) {

List<Identifier.SingleIdentifierValue> keys = new ArrayList<>();
additionalParameters.forEach((k, v) -> keys.add(new Identifier.SingleIdentifierValue(k, v, v == null ? Object.class : v.getClass())));
Copy link
Member

Choose a reason for hiding this comment

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

By using factory/mutator methods on Identifier, there should not be a need to instantiate SingleIdentifierValue from within the code.

*
* @param additionalParameters
*/
public static Identifier fromNamedValues(Map<String, Object> additionalParameters) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's rename the method to createIdentifier(…).

schauder added 5 commits March 1, 2019 14:15
Ids used as backreferences now get properly converted.

Introduced ParentKeys.
ParentKeys hold information about data that needs to be considered for inserts or updates but is not part of the entity.
Appart from column names and values they also hold information about the desired JdbcType in order to facilitate conversions.
This replaces the Map handed around in the past.
ParentKeys gets renamed to Identifier and moved to spring-data-relational.
This facilitates reuse beyond just references to parents.

The factory methods moved to BasicJdbcConverter.
Renamed test class to match default naming pattern for unit tests.
Variables renamed to match changed class names
@schauder schauder force-pushed the issue/DATAJDBC-326 branch from 76dffdd to daa9943 Compare March 1, 2019 13:18
@schauder
Copy link
Contributor Author

schauder commented Mar 1, 2019

Tried to apply the requested changes, except where commented above.

@schauder schauder force-pushed the issue/DATAJDBC-326 branch from daa9943 to aaa894f Compare March 4, 2019 10:40
@schauder
Copy link
Contributor Author

schauder commented Mar 4, 2019

Just force-pushed the next try. I hope I didn't miss the point again.

Add Javadoc. Tweak naming and factory methods. Add equals/hashcode to Identifier. Extend tests.
mp911de pushed a commit that referenced this pull request Mar 5, 2019
Ids used as backreferences now get properly converted.

Introduced Identifier to hold information about data that needs to be considered for inserts or updates but is not part of the entity.
Apart from column names and values they also hold information about the desired JdbcType in order to facilitate conversions.
This replaces the Map handed around in the past.

Original pull request: #118.
mp911de added a commit that referenced this pull request Mar 5, 2019
Add Javadoc. Tweak naming and factory methods. Add equals/hashcode to Identifier. Extend tests.

Original pull request: #118.
@mp911de
Copy link
Member

mp911de commented Mar 5, 2019

That's merged and polished now.

@mp911de mp911de closed this Mar 5, 2019
@mp911de mp911de deleted the issue/DATAJDBC-326 branch March 5, 2019 14:27
THD-Thomas-Lang pushed a commit to THD-Thomas-Lang/spring-data-jdbc that referenced this pull request Apr 12, 2019
Ids used as backreferences now get properly converted.

Introduced Identifier to hold information about data that needs to be considered for inserts or updates but is not part of the entity.
Apart from column names and values they also hold information about the desired JdbcType in order to facilitate conversions.
This replaces the Map handed around in the past.

Original pull request: spring-projects#118.
THD-Thomas-Lang pushed a commit to THD-Thomas-Lang/spring-data-jdbc that referenced this pull request Apr 12, 2019
Add Javadoc. Tweak naming and factory methods. Add equals/hashcode to Identifier. Extend tests.

Original pull request: spring-projects#118.
mp911de added a commit that referenced this pull request Feb 21, 2022
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