eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Overview

Neo4j is a popular graph database management system designed to store, manage, and query data using a graph-based model. We’ll learn how to configure the project and use the various components of Spring Data Neo4j to interact with a Neo4j database.

In this tutorial, we’ll look at how to use Spring Data Neo4j.

2. Project Setup

Let’s start by setting up our project. We’ll create a Spring Boot application that contains entities and repositories that interact with the database. We’ll then look at configuring the project to connect to the database and test the repositories.

2.1. Dependencies

First, let’s add the required dependencies to our project. We’ll add the Spring Boot Starter Data Neo4j dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-neo4j</artifactId>
    <version>2.7.14</version>
</dependency>

2.2. Neo4j Harness

For testing purposes, we’ll use Neo4j Harness:

<dependency>
    <groupId>org.neo4j.test</groupId>
    <artifactId>neo4j-harness</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>

Neo4j Harness is a library that allows us to run a Neo4j database in an embedded mode. This is useful for in-memory testing without installing a Neo4j database.

2.3. Configuring Neo4J Connection

To connect to the database, we need to configure the URI, username, and password. Let’s configure these properties in the application.properties file:

spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=password

The above properties help connect to a local Neo4j database with the username neo4j and password password.

Next, let’s configure the dialect for the database. To do this, we need to create a bean of type org.neo4j.ogm.config.Configuration:

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

Here, we have set the dialect to NEO4J_5. This directs Spring Data Neo4J to generate types and queries using Neo4J 5 specifications.

3. Code Example

Now that we have our project set up, let’s see how to use Spring Data Neo4j to interact with the database. We’ll look at the various components of Spring Data Neo4j and how to use them.

3.1. Neo4J Entities

Let’s start by creating entities that will be used in our repositories.

First, we’ll create a Book entity:

@Node("Book")
public class Book {
    @Id
    private String isbn;
    
    @Property("name")
    private String title;
    
    private Integer year;

    @Relationship(type = "WRITTEN_BY", direction = Relationship.Direction.OUTGOING)
    private Author author;

    // Constructor, getters and setters
}

Let’s look at the annotations used in the above entity:

  • @Node marks the class as a node in the database. We have passed the label of the node as a value to the annotation.
  • We need to mark the primary key of the node with the @Id annotation.
  • If the name of the field in the entity is different from the name of the property in the database, we can use the @Property annotation to specify the name of the property in the database.
  • The @Relationship annotation is used to specify the relationship between two nodes. We need to specify the type of relationship and the direction of the relationship. In this case, we have specified that the relationship is WRITTEN_BY, and the direction is OUTGOING.

Similarly, let’s create the Author entity:

@Node("Author")
public class Author {
    @Id
    private Long id;
    
    private String name;

    @Relationship(type = "WRITTEN_BY", direction = Relationship.Direction.INCOMING)
    private List<Book> books;

    // Constructor, getters and setters
}

As we can see, the Author entity is similar to the Book entity. The only difference is that the Author entity has a list of Book entities, and the direction of the relationship is INCOMING.

3.2. Neo4J Repositories

Next, we’ll create repositories that interact with the database, starting with the BookRepository:

@Repository
public interface BookRepository extends Neo4jRepository<Book, String> {
    Book findOneByTitle(String title);
    List<Book> findAllByYear(Integer year);
}

These methods are similar to the methods in a Spring Data JPA repository. The findOneByTitle() method will find a book by its title, and findAllByYear() will find all books published in a given year.

3.3. Custom Queries

We can also use the @Query annotation to write custom queries.

Let’s create a custom query in our AuthorRepository to find all books of an author written after a given year:

@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);
}

To create the query, we use the MATCH keyword to match the nodes in the database. We specify the labels of the nodes and the relationship between them. Finally, we use the WHERE keyword to specify the conditions for the query.

To pass parameters to the query, we can use the $ symbol. We can use the @Param annotation to specify the parameter’s name in case the name in the query differs from the name of the parameter in the method.

4. Testing

Now that we have our entities and repositories, let’s test them by writing some integration tests for the repositories. We’ll use the Neo4j Harness dependency to run a Neo4j database in embedded mode for testing purposes.

4.1. Configuring Neo4j Harness

Configuring Neo4j Harness can be divided into three steps:

  • Starting an embedded database
  • Setting up the configuration to use the embedded database
  • Cleaning up the database after the tests are run

Let’s set up the embedded server in a test class:

class BookAndAuthorRepositoryIntegrationTest {

    private static Neo4j newServer;
    
    @BeforeAll
    static void initializeNeo4j() {
        newServer = Neo4jBuilders.newInProcessBuilder()
          .withDisabledServer()
          .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() {
        newServer.close();
    }
    
    @DynamicPropertySource
    static void neo4jProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.neo4j.uri", newServer::boltURI);
        registry.add("spring.neo4j.authentication.username", () -> "neo4j");
        registry.add("spring.neo4j.authentication.password", () -> "null");
    }
}

In the above class, we have created a static @BeforeAll method to start the embedded database. We have also created a static @AfterAll method to stop the database after the tests are run.

Let’s take a look at server initialization in depth:

  • We use the newInProcessBuilder() method to obtain a builder instance.
  • The withDisabledServer() property creates a server without HTTP access, as we don’t need to enable outside traffic on our server.
  • Optionally, we can use withFixture() to run an initial Cypher query when the server is created.
  • Here, we provide the query to create two books and an author when the server starts. This helps in the initial data setup if required.

Next, we create a @DynamicPropertySource method to set the properties for the embedded database. We have set the URI, username, and password for the database. This overrides the properties provided in the application.properties file.

4.2. Testing the Repositories

Next, we can add the test methods to test the repositories:

@DataNeo4jTest
class BookAndAuthorRepositoryIntegrationTest {
    
    // harness setup code
    
    @Autowired
    private BookRepository bookRepository;
    
    @Autowired
    private AuthorRepository authorRepository;
    
    @Test
    void givenBookExists_whenFindOneByTitle_thenBookIsReturned() {
        Book book = bookRepository.findOneByTitle("The Fellowship of the Ring");
        assertEquals("978-0547928210", book.getIsbn());
    }

    @Test
    void givenOneBookExistsForYear_whenFindAllByYear_thenOneBookIsReturned() {
        List<Book> books = bookRepository.findAllByYear(1954);
        assertEquals(1, books.size());
    }
    
    @Test
    void givenOneBookExistsAfterYear_whenFindBooksAfterYear_thenOneBookIsReturned() {
        List<Book> books = authorRepository.findBooksAfterYear("J. R. R. Tolkien", 1955);
        assertEquals(1, books.size());
    }
}

The annotation @DataNeo4jTest is used to configure the test class for Spring Data Neo4j. It loads the Spring configuration and creates a test slice for Spring Data Neo4j beans.

Next, we have three test methods to test the findOneByTitle(), findAllByYear(), and findBooksAfterYear() methods.

5. Conclusion

In this article, we learned how to use Spring Data Neo4j to interact with a Neo4j database. We saw how to create entities and repositories and how to write custom queries. Finally, we wrote some integration tests for the repositories.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)