Cách giải quyết lỗi khi chỉ định spring.data.neo4j.database trong Spring Data Neo4j - game nhà cái tặng tiền cược miễn phí

| Mar 14, 2025 min read

Ngày 05 f8bet72 tháng 05 năm 2025 - Máy tính

Trong quá trình sử dụng thực tế của Spring Data Neo4j, tôi đã phát hiện một vấn đề: Sau khi cấu hình TransactionManager tùy chỉnh và chỉ định spring.data.neo4j.database, hệ thống sẽ báo lỗi. Bài viết này sẽ ghi lại, phân tích và cung cấp giải pháp cho vấn đề này, nhằm giúp đỡ những người gặp phải tình huống tương tự.

Trước khi mô tả chi tiết vấn đề, tôi xin liệt kê các phiên bản Java, Spring Data Neo4j và các phụ thuộc khác được sử dụng:

Java: Liberica JDK 17.0.7
Spring Boot: 3.4.5
Spring Data Neo4j: 7.4.5
Maven: 3.9.2

1. Mô tả vấn đề

Để minh họa rõ ràng hơn về vấn đề, tôi đã tạo một dự án Maven đơn giản với cấu trúc thư mục như sau:

spring-data-neo4j-database-config-demo
├─ src
│ ├─ main
│ │ ├─ java
│ │ │ └─ com.example.demo
│ │ │   ├─ config
│ │ │   │ └─ Neo4jConfig.java
│ │ │   ├─ repository
│ │ │   │ └─ ActorRepository.java
│ │ │   ├─ model
│ │ │   │ └─ Actor.java
│ │ │   └─ DemoApplication.java
│ │ └─ resources
│ │   └─ application.yaml
│ └─ test
│   └─ java
│    └─ com.example.demo
│      └─ repository
│       └─ ActorRepositoryTest.java
└─ pom.xml

Như có thể thấy:

  • DemoApplication.java là lớp khởi động ứng dụng.
  • Actor.java là lớp Model, đại diện cho Node Actor trong Neo4j.
  • ActorRepository.java mở rộng interface Neo4jRepository, cung cấp chức năng mặc định để thêm, sửa, xóa và truy vấn Actor.
  • Neo4jConfig.java là lớp cấu hình tùy chỉnh cho Neo4j.
  • ActorRepositoryTest.java là lớp kiểm thử đơn vị dành cho ActorRepository.

Tiếp theo, chúng ta cùng xem qua cấu hình trong file application.yaml:

spring:data:neo4j:database:testneo4j:uri:bolt://localhost:7687authentication:username:neo4jpassword:neo4j

Cấu hình trên không chỉ xác định thông tin kết nối đến Neo4j mà còn sử dụng spring.data.neo4j.database để chỉ định tên cơ sở dữ liệu Neo4j cần kết nối.

Sau đây là đoạn mã của Neo4jConfig.java:

packagecom.example.demo.config;importorg.neo4j.driver.Driver;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;importorg.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;importorg.springframework.transaction.PlatformTransactionManager;importorg.springframework.transaction.annotation.EnableTransactionManagement;@Configuration@EnableTransactionManagement@EnableNeo4jRepositories(basePackages="com.example.demo.repository")publicclass Neo4jConfig {@Bean public PlatformTransactionManager transactionManager(Driver driver) { return Neo4jTransactionManager.with(driver).build(); }}

Từ đoạn mã trên, ta thấy rằng chúng ta đã cấu hình Bean TransactionManager cho Neo4j.

Khi mọi thứ đã sẵn sàng, nếu chạy kiểm thử đơn vị bằng ActorRepositoryTest.java đối với các phương thức CRUD của ActorRepository, hệ thống sẽ xuất hiện lỗi sau:

[ERROR] com.example.demo.repository.ActorRepositoryTest.testSave -- Time elapsed: 1.526 s <<< ERROR!
java.lang.IllegalStateException: Đã có một giao dịch Spring đang diễn ra cho người dùng mặc định của cơ sở dữ liệu mặc định, nhưng bạn yêu cầu người dùng mặc định của 'test'
	at org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager.retrieveTransaction(Neo4jTransactionManager.java:244)
	...

Lỗi xảy ra tại dòng 244 của lớp Neo4jTransactionManager.java trong Spring Data Neo4j. Thông điệp lỗi quan trọng nhấn mạnh rằng: “Đã có một giao dịch Spring đang diễn ra cho người dùng mặc định của cơ sở dữ liệu mặc định, nhưng bạn yêu cầu người dùng mặc định của ’test’”.

2. Phân tích nguyên nhân

Kiểm tra mã nguồn của lớp Neo4jTransactionManager.java trong Spring Data Neo4j và kết hợp với thông tin từ lỗi, ta nhận thấy rằng giá trị trả về bởi getDatabaseSelection()getUserSelection() không khớp nhau.

Tức là dù đã chỉ định cơ sở dữ liệu cần kết nối trong file application.yaml, nhưng TransactionManager vẫn nhận giá trị là cơ sở dữ liệu mặc định. Vấn đề có thể nằm ở lớp cấu hình tùy chỉnh Neo4jConfig.java.

3. Giải pháp

Dựa trên nguyên nhân tiềm năng, chúng ta thử tham khảo tài liệu và chỉnh sửa Neo4jConfig.java để chỉ định cơ sở dữ liệu cần kết nối khi cấu hình TransactionManager. Điều này có thể giúp giải quyết vấn đề.

Sau khi chỉnh sửa, đoạn mã mới của Neo4jConfig.java như sau:

packagecom.example.demo.config;importorg.neo4j.driver.Driver;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.neo4j.core.DatabaseSelection;importorg.springframework.data.neo4j.core.DatabaseSelectionProvider;importorg.springframework.data.neo4j.core.Neo4jClient;importorg.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;importorg.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;importorg.springframework.transaction.PlatformTransactionManager;importorg.springframework.transaction.annotation.EnableTransactionManagement;@Configuration@EnableTransactionManagement@EnableNeo4jRepositories(basePackages="com.example.demo.repository")publicclass Neo4jConfig {@Value("${spring.data.neo4j.database}") private String database; @Bean public DatabaseSelectionProvider databaseSelectionProvider() { return () -> DatabaseSelection.byName(database); } @Bean public Neo4jClient neo4jClient(Driver driver, DatabaseSelectionProvider provider) { return Neo4jClient.with(driver).withDatabaseSelectionProvider(provider).build(); } @Bean public PlatformTransactionManager transactionManager(Driver driver, DatabaseSelectionProvider provider) { return Neo4jTransactionManager.with(driver).withDatabaseSelectionProvider(provider).build(); }}

Trong đoạn mã trên, chúng ta đã đọc giá trị của spring.data.neo4j.database và sử dụng nó để tạo Bean DatabaseSelectionProvider tùy chỉnh. Sau đó, Bean Neo4jClientTransactionManager đều sử dụng Provider này.

Sau khi áp dụng thay đổi, chạy lại kiểm thử đơn 7win vị bằng game nhà cái tặng tiền cược miễn phí ActorRepositoryTest.java, không còn lỗi nào xảy ra.

4. Kết luận

Bài viết này đã mô tả, phân tích và đưa ra giải pháp cho vấn đề xảy ra khi cấu hình TransactionManager tùy chỉnh trong Spring Data Neo4j và chỉ định spring.data.neo4j.database.

Mã nguồn đầy đủ của ví dụ này đã được đăng tải lên GitHub, mời các bạn theo dõi hoặc Fork.

[1] Spring: FAQ về cách cấu hình tên cơ sở dữ liệu trong Spring Data JPA - [2] GitHub: Lớp Neo4jTransactionManager.java trong Spring Data Neo4j -

#Spring #Java #Neo4j