Core Features (PersistenceManager)
Fluent Query Building
Section titled “Fluent Query Building”val activeAdults = manager.query( QuerySpecification .withStatement("MATCH (p:Person) RETURN properties(p)") .transform(Person::class.java) .filter { it.age >= 18 } // Client-side filtering .filter { it.email != null } .map { it.firstName } // Transform to String .limit(10))Chainable Transformations
Section titled “Chainable Transformations”val fullNames: List<String> = manager.query( QuerySpecification .withStatement("MATCH (p:Person) RETURN properties(p)") .transform(Person::class.java) // Map to Person .filter { it.age > 25 } // Filter .map { "${it.firstName} ${it.lastName}" } // Transform to String)Transaction Management
Section titled “Transaction Management”@Componentclass UserService @Autowired constructor( private val personRepo: PersonRepository, private val emailService: EmailService) { @Transactional // Spring's @Transactional works fun registerUser(person: Person) { val created = personRepo.create(person) emailService.sendWelcome(created.email) // Auto-commits on success, rolls back on exception }
@DrivineTransactional // Or use Drivine's annotation fun updateUserProfile(uuid: String, updates: Partial<Person>) { personRepo.update(uuid, updates) }}Object-manager saves join these transactions: see Saves and transactions for what a refused save does to one.
Partial Updates
Section titled “Partial Updates”val updates = partial<Person> { set(Person::email, "newemail@example.com") set(Person::age, 30)}personRepo.update(personId, updates)External Query Files
Section titled “External Query Files”Place .cypher files in src/main/resources/queries/:
MATCH (p:Person)WHERE p.isActive = trueRETURN properties(p)Load and use:
@Configurationclass QueryConfig @Autowired constructor( private val loader: QueryLoader) { @Bean fun findActiveUsers() = CypherStatement(loader.load("findActiveUsers"))}
@Componentclass PersonRepository @Autowired constructor( @Qualifier("neoManager") val manager: PersistenceManager, val findActiveUsers: CypherStatement) { fun getActive(): List<Person> { return manager.query( QuerySpecification .withStatement(findActiveUsers.statement) .transform(Person::class.java) ) }}Multiple Query Results
Section titled “Multiple Query Results”// Expect exactly one result (throws if 0 or >1)val person: Person = manager.getOne(spec)
// Expect 0 or 1 result (returns null if not found)val maybePerson: Person? = manager.maybeGetOne(spec)
// Return all resultsval people: List<Person> = manager.query(spec)
// Execute without returning results (for mutations)manager.execute(spec)
