O que spring-data-neo4j faz?
Fornece padrões de integração do Spring Data Neo4j para aplicações Spring Boot. Use quando precisar trabalhar com um banco de dados de grafos, nós e relacionamentos do Neo4j, consultas Cypher ou Spring Data Neo4j. Cria entidades de nó com a anotação @Node, define relacionamentos com @Relationship, escreve consultas Cypher usando @Query, configura repositórios Neo4j imperativos e reativos, implementa padrões de travessia de grafos e configura testes com bancos de dados embutidos.
Configuração
Adicione a dependência spring-boot-starter-data-neo4j ao seu arquivo pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
Configure a conexão com o banco de dados Neo4j no arquivo application.properties:
spring.neo4j.uri=bolt://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=password
Entidades de Nó
Crie uma entidade de nó usando a anotação @Node:
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Property;
@Node
public class Movie {
@Id
private Long id;
@Property("title")
private String title;
private Integer year;
// Construtores, getters e setters
public Movie() {}
public Movie(Long id, String title, Integer year) {
this.id = id;
this.title = title;
this.year = year;
}
// Getters e Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
}
Relacionamentos
Defina relacionamentos entre nós usando a anotação @Relationship:
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Relationship;
import java.util.ArrayList;
import java.util.List;
@Node
public class Person {
@Id
private Long id;
private String name;
@Relationship(type = "ACTED_IN", direction = Relationship.Direction.OUTGOING)
private List<Movie> movies = new ArrayList<>();
// Construtores, getters e setters
public Person() {}
public Person(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Movie> getMovies() {
return movies;
}
public void setMovies(List<Movie> movies) {
this.movies = movies;
}
}
Repositórios
Crie um repositório imperativo ou reativo para suas entidades:
Repositório Imperativo
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MovieRepository extends Neo4jRepository<Movie, Long> {
}
Repositório Reativo
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MovieRepository extends ReactiveNeo4jRepository<Movie, Long> {
}
Consultas Cypher Personalizadas
Use a anotação @Query para escrever consultas Cypher personalizadas:
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MovieRepository extends Neo4jRepository<Movie, Long> {
@Query("MATCH (m:Movie) WHERE m.year > $year RETURN m")
List<Movie> findMoviesByYearGreaterThan(@Param("year") Integer year);
@Query("MATCH (p:Person)-[:ACTED_IN]->(m:Movie) WHERE m.title = $title RETURN p")
List<Person> findActorsByMovieTitle(@Param("title") String title);
}
Travessia de Grafos
Implemente padrões de travessia utilizando Cypher ou APIs do Spring Data Neo4j:
@Service
public class RecommendationService {
@Autowired
private MovieRepository movieRepository;
public List<Movie> recommendMoviesForPerson(Long personId) {
return movieRepository.findMoviesRecommendedFor(personId);
}
}
@Repository
public interface MovieRepository extends Neo4jRepository<Movie, Long> {
@Query("MATCH (p:Person {id: $personId})-[:RATED]->(m:Movie)<-[:RATED]-(other:Person)-[:RATED]->(rec:Movie) WHERE NOT (p)-[:RATED]->(rec) RETURN DISTINCT rec")
List<Movie> findMoviesRecommendedFor(@Param("personId") Long personId);
}
Testes com Banco Embutido
Configure testes usando um banco de dados Neo4j embutido com a biblioteca neo4j-harness:
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<scope>test</scope>
</dependency>
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.neo4j.harness.Neo4j;
import org.neo4j.harness.Neo4jBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
@SpringBootTest
public class Neo4jIntegrationTest {
private static Neo4j embeddedDatabaseServer;
@BeforeAll
static void startNeo4j() {
embeddedDatabaseServer = Neo4jBuilders.newInProcessBuilder().build();
}
@AfterAll
static void stopNeo4j() {
embeddedDatabaseServer.close();
}
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", embeddedDatabaseServer::boltURI);
registry.add("spring.neo4j.authentication.username", () -> "neo4j");
registry.add("spring.neo4j.authentication.password", () -> "password");
}
@Autowired
private MovieRepository movieRepository;
@Test
public void testMovieCreation() {
Movie movie = new Movie(1L, "Inception", 2010);
movieRepository.save(movie);
Movie found = movieRepository.findById(1L).orElseThrow();
assertEquals("Inception", found.getTitle());
}
}
Considerações Adicionais
- Certifique-se de que o banco de dados Neo4j esteja em execução antes de iniciar a aplicação.
- Para ambientes de produção, configure a autenticação e a conexão segura via HTTPS ou Bolt + TLS.
- Utilize índices no Neo4j para otimizar consultas Cypher frequentes.
- A versão 4.x do Spring Data Neo4j requer Java 8 ou superior e Spring Boot 2.4+.
- Para operações reativas, certifique-se de usar o driver Bolt reativo e dependências como
spring-boot-starter-webflux.