Skip to content

@NodeLabels Annotation

Maps a set-valued field to the node’s labels, beyond the fixed ones the fragment declares. The field is filled from the node’s labels on load and written as real labels on save, so MATCH (n:Admin) finds a node whose field holds Admin.

enum class Role { Admin, Reviewer, Author }
@NodeFragment(labels = ["Person"])
data class PersonNode(
@NodeId val id: String,
@NodeLabels val roles: Set<Role>, // a closed set: only these labels are the field's
)
@NodeFragment(labels = ["Thing"])
data class ThingNode(
@NodeId val id: String,
@NodeLabels val labels: Set<String>, // an open set: any label
)

Saving follows NullPolicy, as every field does:

IGNORE (default) CLEAR
Labels in the field added added
Labels that are the field’s and not in it left removed

Which labels are the field’s depends on its element type:

  • An enum: its members. It reads only those, and a label outside the enum is ignored, never an error. An enum may not name one of the fragment’s own labels.
  • String: the labels it has itself written, which it records on the node in the list property __drivine.labels.<fieldName>. Because the record is on the node, a CLEAR save removes the same labels whichever process loaded the object, or if none did. It reads every label the node carries, so an object loaded and then saved under CLEAR takes on all the labels it read.

A label that is not the field’s — the fragment’s own, another fragment’s, one written by other code — is never removed. Names beginning __drivine. are reserved: a field or bag may not use them.

A fragment may carry one @NodeLabels field. saveAll saves such a fragment one statement per object. On a relationship target in a @GraphView, a String field adds and does not remove.