Back to Database & SQL

spring-data-neo4j

Spring DataNeo4jGraph DatabaseJavaSpring BootCypherReactive ProgrammingData Modeling
282📄 MIT🕒 2026-06-15Source ↗

Install this skill

npx skills add giuseppe-trisciuoglio/developer-kit

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

Spring Data Neo4j (SDN) bridges the gap between object-oriented domain models and graph data structures. It maps Java objects to Neo4j nodes and relationships, handling complex graph traversals through familiar Spring Repository patterns. The framework supports both blocking imperative styles and non-blocking reactive paradigms using Project Reactor. Developers can define entity relationships via annotations, implement automated query derivation from interface methods, or execute raw Cypher queries when specific graph traversals are required. By integrating directly with Spring Boot's dependency injection and transaction management, SDN simplifies graph database interaction. It manages entity state, ID generation strategies, and mapping conversions, allowing teams to focus on business logic rather than manual database connectivity or low-level driver serialization concerns.

When to Use This Skill

  • Building social networking applications with deep multi-level relationship traversals
  • Modeling complex domain data where connections between entities carry significant weight
  • Implementing recommendation engines based on path discovery and node similarities
  • Managing hierarchical or network-based data structures in a microservices environment

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • setup spring data neo4j in my boot project
  • map a graph relationship between two entities in java
  • write a custom cypher query inside a spring repository
  • how to use reactive neo4j repository with spring boot
  • define a node entity with a business key in neo4j
  • troubleshoot relationship mapping in spring data neo4j

Pro Tips

  • 💡Always define clear relationship directions and types to optimize query performance and ensure semantic clarity in your graph model.
  • 💡Utilize the `Neo4jTemplate` for complex, dynamic queries or batch operations that are difficult to express via derived repository methods.
  • 💡Leverage Spring's `@Transactional` annotation for graph operations to ensure data consistency, especially when modifying multiple nodes or relationships.

What this skill does

  • Object-Graph mapping for Java entities using @Node and @Relationship
  • Automatic repository implementation for standard CRUD and derived query methods
  • Support for reactive data access using Flux and Mono via ReactiveNeo4jRepository
  • Custom Cypher execution with parameter binding via @Query annotations
  • Configurable ID generation strategies for business keys versus synthetic primary keys

When not to use it

  • Handling simple key-value pairs or highly structured, tabular data better suited for RDBMS
  • Applications with extremely high write-heavy throughput requirements where graph locks create bottlenecks
  • Small projects where the overhead of an graph database and OGM framework introduces unnecessary complexity

Example workflow

  1. Add the spring-boot-starter-data-neo4j dependency to the project build file
  2. Define POJO domain classes annotated with @Node to represent graph entities
  3. Establish relationships between entities using @Relationship annotations
  4. Create repository interfaces extending Neo4jRepository for data access
  5. Inject repositories into service beans to perform graph queries and persistence

Prerequisites

  • Active Neo4j database instance (version 4.x or 5.x)
  • Familiarity with Cypher query language basics
  • Spring Boot project foundation

Pitfalls & limitations

  • !Mixing imperative and reactive repository styles in the same application leads to unpredictable threading and connectivity issues
  • !Over-fetching large subgraphs into memory by defining overly eager relationships
  • !Incorrect handling of bidirectional relationships resulting in infinite recursion during mapping

FAQ

Can I use both Neo4jRepository and ReactiveNeo4jRepository together?
No. The framework requires a single paradigm choice. Mixing blocking and reactive drivers within the same application context causes conflicts in connection handling.
How does Spring Data Neo4j handle entity IDs?
You can either use @GeneratedValue for system-assigned IDs or mark a specific field with @Id as a business key to enforce custom identity constraints.
Is the Cypher-DSL required for custom queries?
It is optional, but recommended for building type-safe queries. You can always use standard string-based Cypher within the @Query annotation.

How it compares

SDN automates the complex mapping of graph traversals to objects, which is significantly more error-prone when manually managing raw database drivers and Cypher result parsing.

Source & trust

282 stars📄 MIT🕒 Updated 2026-06-15
📄 Full skill instructions — original source: giuseppe-trisciuoglio/developer-kit
# Spring Data Neo4j Integration Patterns

## When to Use This Skill

To use this skill when you need to:
- Set up Spring Data Neo4j in a Spring Boot application
- Create and map graph node entities and relationships
- Implement Neo4j repositories with custom queries
- Write Cypher queries using @Query annotations
- Configure Neo4j connections and dialects
- Test Neo4j repositories with embedded databases
- Work with both imperative and reactive Neo4j operations
- Map complex graph relationships with bidirectional or unidirectional directions
- Use Neo4j's internal ID generation or custom business keys

## Overview

Spring Data Neo4j provides three levels of abstraction for Neo4j integration:
- **Neo4j Client**: Low-level abstraction for direct database access
- **Neo4j Template**: Medium-level template-based operations
- **Neo4j Repositories**: High-level repository pattern with query derivation

Key features include reactive and imperative operation modes, immutable entity mapping, custom query support via @Query annotation, Spring's Conversion Service integration, and full support for graph relationships and traversals.

## Quick Setup

### Dependencies

**Maven:**
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>


**Gradle:**
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-neo4j'
}


### Configuration

**application.properties:**
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=secret


**Configure Neo4j Cypher-DSL Dialect:**
@Configuration
public class Neo4jConfig {

@Bean
Configuration cypherDslConfiguration() {
return Configuration.newConfig()
.withDialect(Dialect.NEO4J_5).build();
}
}


## Basic Entity Mapping

### Node Entity with Business Key

@Node("Movie")
public class MovieEntity {

@Id
private final String title; // Business key as ID

@Property("tagline")
private final String description;

private final Integer year;

@Relationship(type = "ACTED_IN", direction = Direction.INCOMING)
private List<Roles> actorsAndRoles = new ArrayList<>();

@Relationship(type = "DIRECTED", direction = Direction.INCOMING)
private List<PersonEntity> directors = new ArrayList<>();

public MovieEntity(String title, String description, Integer year) {
this.title = title;
this.description = description;
this.year = year;
}
}


### Node Entity with Generated ID

@Node("Movie")
public class MovieEntity {

@Id @GeneratedValue
private Long id;

private final String title;

@Property("tagline")
private final String description;

public MovieEntity(String title, String description) {
this.id = null; // Never set manually
this.title = title;
this.description = description;
}

// Wither method for immutability with generated IDs
public MovieEntity withId(Long id) {
if (this.id != null && this.id.equals(id)) {
return this;
} else {
MovieEntity newObject = new MovieEntity(this.title, this.description);
newObject.id = id;
return newObject;
}
}
}


## Repository Patterns

### Basic Repository Interface

@Repository
public interface MovieRepository extends Neo4jRepository<MovieEntity, String> {

// Query derivation from method name
MovieEntity findOneByTitle(String title);

List<MovieEntity> findAllByYear(Integer year);

List<MovieEntity> findByYearBetween(Integer startYear, Integer endYear);
}


### Reactive Repository

@Repository
public interface MovieRepository extends ReactiveNeo4jRepository<MovieEntity, String> {

Mono<MovieEntity> findOneByTitle(String title);

Flux<MovieEntity> findAllByYear(Integer year);
}


**Imperative vs Reactive:**
- Use Neo4jRepository for blocking, imperative operations
- Use ReactiveNeo4jRepository for non-blocking, reactive operations
- **Do not mix imperative and reactive in the same application**
- Reactive requires Neo4j 4+ on the database side

## Custom Queries with @Query

@Repository
public interface AuthorRepository extends Neo4jRepository<Author, Long> {

@Query("MATCH (b:Book)-[:WRITTEN_BY]->(a:Author) " +
"WHERE a.name = $name AND b.year > $year " +
"RETURN b")
List<Book> findBooksAfterYear(@Param("name") String name,
@Param("year") Integer year);

@Query("MATCH (b:Book)-[:WRITTEN_BY]->(a:Author) " +
"WHERE a.name = $name " +
"RETURN b ORDER BY b.year DESC")
List<Book> findBooksByAuthorOrderByYearDesc(@Param("name") String name);
}


**Custom Query Best Practices:**
- Use $parameterName for parameter placeholders
- Use @Param annotation when parameter name differs from method parameter
- MATCH specifies node patterns and relationships
- WHERE filters results
- RETURN defines what to return

## Testing Strategies

### Neo4j Harness for Integration Testing

**Test Configuration:**
@DataNeo4jTest
class BookRepositoryIntegrationTest {

private static Neo4j embeddedServer;

@BeforeAll
static void initializeNeo4j() {
embeddedServer = Neo4jBuilders.newInProcessBuilder()
.withDisabledServer() // No HTTP access needed
.withFixture(
"CREATE (b:Book {isbn: '978-0547928210', " +
"name: 'The Fellowship of the Ring', year: 1954})" +
"-[:WRITTEN_BY]->(a:Author {id: 1, name: 'J. R. R. Tolkien'}) " +
"CREATE (b2:Book {isbn: '978-0547928203', " +
"name: 'The Two Towers', year: 1956})" +
"-[:WRITTEN_BY]->(a)"
)
.build();
}

@AfterAll
static void stopNeo4j() {
embeddedServer.close();
}

@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", embeddedServer::boltURI);
registry.add("spring.neo4j.authentication.username", () -> "neo4j");
registry.add("spring.neo4j.authentication.password", () -> "null");
}

@Autowired
private BookRepository bookRepository;

@Test
void givenBookExists_whenFindOneByTitle_thenBookIsReturned() {
Book book = bookRepository.findOneByTitle("The Fellowship of the Ring");
assertThat(book.getIsbn()).isEqualTo("978-0547928210");
}
}


## Examples

Progress from basic to advanced examples covering complete movie database, social network patterns, e-commerce product catalogs, custom queries, and reactive operations.

See [examples](./references/examples.md) for comprehensive code examples.

## Best Practices

### Entity Design
- Use immutable entities with final fields
- Choose between business keys (@Id) or generated IDs (@Id @GeneratedValue)
- Keep entities focused on graph structure, not business logic
- Use proper relationship directions (INCOMING, OUTGOING, UNDIRECTED)

### Repository Design
- Extend Neo4jRepository for imperative or ReactiveNeo4jRepository for reactive
- Use query derivation for simple queries
- Write custom @Query for complex graph patterns
- Don't mix imperative and reactive in same application

### Configuration
- Always configure Cypher-DSL dialect explicitly
- Use environment-specific properties for credentials
- Never hardcode credentials in source code
- Configure connection pooling based on load

### Testing
- Use Neo4j Harness for integration tests
- Provide test data via withFixture() Cypher queries
- Use @DataNeo4jTest for test slicing
- Test both successful and edge-case scenarios

### Architecture
- Use constructor injection exclusively
- Separate domain entities from DTOs
- Follow feature-based package structure
- Keep domain layer framework-agnostic

### Security
- Use Spring Boot property overrides for credentials
- Configure proper authentication and authorization
- Validate input parameters in service layer
- Use parameterized queries to prevent Cypher injection

## References

For detailed documentation including complete API reference, Cypher query patterns, and configuration options:

- [Annotations Reference](./references/reference.md#annotations-reference)
- [Cypher Query Language](./references/reference.md#cypher-query-language)
- [Configuration Properties](./references/reference.md#configuration-properties)
- [Repository Methods](./references/reference.md#repository-methods)
- [Projections and DTOs](./references/reference.md#projections-and-dtos)
- [Transaction Management](./references/reference.md#transaction-management)
- [Performance Tuning](./references/reference.md#performance-tuning)

### External Resources
- [Spring Data Neo4j Official Documentation](https://docs.spring.io/spring-data/neo4j/reference/)
- [Neo4j Developer Guide](https://neo4j.com/developer/)
- [Spring Data Commons Documentation](https://docs.spring.io/spring-data/commons/reference/)

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/spring-data-neo4j/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/giuseppe-trisciuoglio/developer-kit/spring-data-neo4j/SKILL.md
  • Cursor: ~/.cursor/skills/giuseppe-trisciuoglio/developer-kit/spring-data-neo4j/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/giuseppe-trisciuoglio/developer-kit/spring-data-neo4j/SKILL.md

🚀 Install with CLI:
npx skills add giuseppe-trisciuoglio/developer-kit

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid database & sql issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Database & SQL and is published by Giuseppe Trisciuoglio, maintained in giuseppe-trisciuoglio/developer-kit.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.