Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Parameterize Node DynamicLabels #3034

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

Open
garbybaby wants to merge 1 commit into spring-projects:7.4.x
base: 7.4.x
Choose a base branch
Loading
from garbybaby:parameterize_label_dynamic
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ final class DynamicLabels implements UnaryOperator<OngoingMatchAndUpdate> {
public OngoingMatchAndUpdate apply(OngoingMatchAndUpdate ongoingMatchAndUpdate) {

OngoingMatchAndUpdate decoratedMatchAndUpdate = ongoingMatchAndUpdate;

if (oldLabels.equals(newLabels) || oldLabels.isEmpty()) {
// Returning if old label equals new label or old labels are empty, nothing to do here
return decoratedMatchAndUpdate;
}

if (!oldLabels.isEmpty()) {
decoratedMatchAndUpdate = decoratedMatchAndUpdate.remove(rootNode, oldLabels.toArray(new String[0]));
}
Expand All @@ -60,4 +66,8 @@ public OngoingMatchAndUpdate apply(OngoingMatchAndUpdate ongoingMatchAndUpdate)
}
Copy link

@zakjan zakjan Aug 22, 2025
edited
Loading

Choose a reason for hiding this comment

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

oldLabels.toArray(new String[0]) -> Cypher.parameter("oldLabels")
newLabels.toArray(new String[0]) -> Cypher.parameter("newLabels")

Parameter names are to be added to Constants and populated to the query when running it.

michael-simons reacted with thumbs up emoji
return decoratedMatchAndUpdate;
}

public List<String> getNewLabels() {
return newLabels;
}
}
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,10 @@ private <T> T saveImpl(T instance, @Nullable Collection<PropertyFilter.Projected

DynamicLabels dynamicLabels = determineDynamicLabels(entityToBeSaved, entityMetaData);

// Clear existing dynamic labels and populate the list with the updated set of labels.
entityMetaData.getDynamicLabels().clear();
entityMetaData.getDynamicLabels().addAll(dynamicLabels.getNewLabels());

@SuppressWarnings("unchecked") // Applies to retrieving the meta data
TemplateSupport.FilteredBinderFunction<T> binderFunction = TemplateSupport.createAndApplyPropertyFilter(
includedProperties, entityMetaData,
Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ private <T> Mono<T> saveImpl(T instance, @Nullable Collection<PropertyFilter.Pro

DynamicLabels dynamicLabels = t.getT2();

// Clear existing dynamic labels and populate the list with the updated set of labels.
entityMetaData.getDynamicLabels().clear();
entityMetaData.getDynamicLabels().addAll(dynamicLabels.getNewLabels());

@SuppressWarnings("unchecked")
FilteredBinderFunction<T> binderFunction = TemplateSupport.createAndApplyPropertyFilter(
includedProperties, entityMetaData,
Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
String primaryLabel = nodeDescription.getPrimaryLabel();
List<String> additionalLabels = nodeDescription.getAdditionalLabels();

List<String> additionalLabelsNew = new ArrayList<>(additionalLabels);
additionalLabelsNew.addAll(nodeDescription.getDynamicLabels());
Node rootNodeWithDynamicLabels = node(primaryLabel, additionalLabelsNew).named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription));
Copy link

@zakjan zakjan Aug 22, 2025
edited
Loading

Choose a reason for hiding this comment

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

This still generates a non-parametrized query for @DynamicLabels.


Node rootNode = node(primaryLabel, additionalLabels).named(Constants.NAME_OF_TYPED_ROOT_NODE.apply(nodeDescription));
IdDescription idDescription = nodeDescription.getIdDescription();
Assert.notNull(idDescription, "Cannot save individual nodes without an id attribute");
Expand All @@ -320,9 +324,9 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
.where(createCompositePropertyCondition(idPropertyDescription, possibleExistingNode.getRequiredSymbolicName(), idParameter))
.with(possibleExistingNode)
.where(possibleExistingNode.isNull())
.create(rootNode.withProperties(versionProperty, literalOf(0)))
.with(rootNode)
.mutate(rootNode, parameter(Constants.NAME_OF_PROPERTIES_PARAM))).returning(rootNode)
.create(rootNodeWithDynamicLabels.withProperties(versionProperty, literalOf(0)))
.with(rootNodeWithDynamicLabels)
.mutate(rootNodeWithDynamicLabels, parameter(Constants.NAME_OF_PROPERTIES_PARAM))).returning(rootNodeWithDynamicLabels)
.build();

Statement updateIfExists = updateDecorator.apply(match(rootNode)
Expand All @@ -345,9 +349,9 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
.where(createCompositePropertyCondition(idPropertyDescription, possibleExistingNode.getRequiredSymbolicName(), idParameter))
.with(possibleExistingNode)
.where(possibleExistingNode.isNull())
.create(rootNode)
.with(rootNode)
.mutate(rootNode, parameter(Constants.NAME_OF_PROPERTIES_PARAM))).returning(rootNode)
.create(rootNodeWithDynamicLabels)
.with(rootNodeWithDynamicLabels)
.mutate(rootNodeWithDynamicLabels, parameter(Constants.NAME_OF_PROPERTIES_PARAM))).returning(rootNodeWithDynamicLabels)
.build();

Statement updateIfExists = updateDecorator.apply(match(rootNode)
Expand Down Expand Up @@ -375,10 +379,10 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
.where(nodeIdFunction.apply(possibleExistingNode).isEqualTo(idParameter))
.with(possibleExistingNode)
.where(possibleExistingNode.isNull())
.create(rootNode.withProperties(versionProperty, literalOf(0)))
.with(rootNode)
.mutate(rootNode, parameter(Constants.NAME_OF_PROPERTIES_PARAM)))
.returning(rootNode)
.create(rootNodeWithDynamicLabels.withProperties(versionProperty, literalOf(0)))
.with(rootNodeWithDynamicLabels)
.mutate(rootNodeWithDynamicLabels, parameter(Constants.NAME_OF_PROPERTIES_PARAM)))
.returning(rootNodeWithDynamicLabels)
.build();

updateIfExists = updateDecorator.apply(match(rootNode)
Expand All @@ -393,9 +397,9 @@ public Statement prepareSaveOf(NodeDescription<?> nodeDescription,
} else {
createIfNew = updateDecorator
.apply(optionalMatch(possibleExistingNode).where(nodeIdFunction.apply(possibleExistingNode).isEqualTo(idParameter))
.with(possibleExistingNode).where(possibleExistingNode.isNull()).create(rootNode)
.set(rootNode, parameter(Constants.NAME_OF_PROPERTIES_PARAM)))
.returning(rootNode).build();
.with(possibleExistingNode).where(possibleExistingNode.isNull()).create(rootNodeWithDynamicLabels)
.set(rootNodeWithDynamicLabels, parameter(Constants.NAME_OF_PROPERTIES_PARAM)))
.returning(rootNodeWithDynamicLabels).build();

updateIfExists = updateDecorator.apply(match(rootNode).where(nodeIdFunction.apply(rootNode).isEqualTo(idParameter))
.mutate(rootNode, parameter(Constants.NAME_OF_PROPERTIES_PARAM))).returning(rootNode).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ final class DefaultNeo4jPersistentEntity<T> extends BasicPersistentEntity<T, Neo

private final Lazy<List<String>> additionalLabels;

private List<String> dynamicLabels;

/**
* Projections need to be also be eligible entities but don't define id fields.
*/
Expand All @@ -90,8 +92,8 @@ final class DefaultNeo4jPersistentEntity<T> extends BasicPersistentEntity<T, Neo

DefaultNeo4jPersistentEntity(TypeInformation<T> information) {
super(information);

this.primaryLabel = computePrimaryLabel(this.getType());
this.dynamicLabels = new ArrayList<>();
this.primaryLabel = computePrimaryLabel(this.getType());
this.additionalLabels = Lazy.of(this::computeAdditionalLabels);
this.graphProperties = Lazy.of(this::computeGraphProperties);
this.dynamicLabelsProperty = Lazy.of(() -> getGraphProperties().stream().map(Neo4jPersistentProperty.class::cast)
Expand Down Expand Up @@ -166,6 +168,11 @@ public List<String> getAdditionalLabels() {
return this.additionalLabels.get();
}

@Override
public List<String> getDynamicLabels() {
return this.dynamicLabels;
}

/*
* (non-Javadoc)
* @see NodeDescription#getGraphProperty(String)
Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public interface NodeDescription<T> {
*/
List<String> getAdditionalLabels();

/**
* @return a list of dynamic label names applied to the entity
*/
List<String> getDynamicLabels();

/**
* @return The list of all static labels, that is the union of {@link #getPrimaryLabel()} +
* {@link #getAdditionalLabels()}. Order is guaranteed to be the primary first, then the others.
Expand Down

AltStyle によって変換されたページ (->オリジナル) /