英文:
Problem with application with spring-boot-starter-data-mongodb and spring-boot-starter-data-jdbc
问题
我有一个使用MongoDB作为持久层的合成应用程序,使用MongoRepository。我在这里使用spring-boot-starter-data-mongodb。这个方法有效。
现在我想添加另一个数据源来连接到一个带有JDBC的数据库。我想在同一个项目中使用spring-boot-starter-data-jdbc。
这两种解决方案都可以在没有另一个的情况下完美运行。
配置
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- db2 driver -->
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc</artifactId>
<version>db2jcc4</version>
</dependency>
application.properties
spring.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver
spring.datasource.url=jdbc:db2://db2host:58440/db
spring.datasource.username=user
spring.datasource.password=thePassword
spring.data.mongodb.host=mongohost
我有两个Repositories:
KundeRepository
package com.example.demo.adapter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface KundeRepository extends MongoRepository<KundeRepository.Kunde, String> {
Kunde findByName(String name);
public static record Kunde(@Id String id, String name) {
}
}
package com.example.demo.adapter;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
public interface KometRepository extends Repository<KometRepository.Abrechnungsdaten, Long> {
@Query("SELECT NEID, LIEGID, SALDO FROM THETABLE AS ena WHERE ena.LIEGID = :blubb")
List<Abrechnungsdaten> abrechnungsdaten(@Param("blubb") Long blubb);
public static record Abrechnungsdaten(
@Column("LIEGID") Long liegid,
@Column("NEID") Byte neid,
@Column("SALDO") BigDecimal saldo) {
}
}
package com.example.demo.adapter;
import java.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EvalController {
@Autowired
KometRepository kometRepository;
@Autowired
KundeRepository kundeRepository;
@GetMapping("komet")
public KometRepository.Abrechnungsdaten steuerdaten() {
return kometRepository.abrechnungsdaten(5675384L);
}
@GetMapping("mongo")
public KundeRepository.Kunde bla() {
var name = "Jens";
kundeRepository.save(new KundeRepository.Kunde("nne", name));
return kundeRepository.findByName(null);
}
}
这两个Repositories在没有另一个的情况下都可以工作。然而,一起使用时我得到以下错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field kometRepository in com.example.demo.adapter.EvalController required a bean of type 'com.example.demo.adapter.KometRepository' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.demo.adapter.KometRepository' in your configuration.
我错过了什么?
英文:
I have an synthetic application that runs with a mongodb in the persistence layer with a MongoRepository. I use spring-boot-starter-data-mongodb for this. That works.
Now I want to add another DataSource to connect to a Database with JDBC. I want to use spring-boot-starter-data-jdbc in the same project.
Both solutions work perfectly without the other one
Configuration
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- db2 driver -->
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc</artifactId>
<version>db2jcc4</version>
</dependency>
application.properties
spring.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver
spring.datasource.url=jdbc:db2://db2host:58440/db
spring.datasource.username=user
spring.datasource.password=thePassword
spring.data.mongodb.host=mongohost
I have two Repositories:
KundeRepository
package com.example.demo.adapter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface KundeRepository extends MongoRepository<KundeRepository.Kunde, String>{
Kunde findByName(String name);
public static record Kunde(@Id String id, String name) {
}
}
package com.example.demo.adapter;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
public interface KometRepository extends Repository<KometRepository.Abrechnungsdaten, Long> {
@Query("""
SELECT NEID, LIEGID, SALDO
FROM THETABLE AS ena
WHERE ena.LIEGID = :blubb
""")
List<Abrechnungsdaten> abrechnungsdaten(@Param("blubb") Long blubb);
public static record Abrechnungsdaten(
@Column("LIEGID") Long liegid,
@Column("NEID") Byte neid,
@Column("SALDO") BigDecimal saldo) {
}
}
package com.example.demo.adapter;
import java.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EvalController {
@Autowired
KometRepository kometRepository;
@Autowired
KundeRepository kundeRepository;
@GetMapping("komet")
public KometRepository.Abrechnungsdaten steuerdaten(){
return kometRepository.abrechnungsdaten(5675384L);
}
@GetMapping("mongo")
public KundeRepository.Kunde bla(){
var name = "Jens";
kundeRepository.save(new KundeRepository.Kunde("nne", name));
return kundeRepository.findByName(null);
}
}
Both Repositories works without the other. However, together I get this Error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field kometRepository in com.example.demo.adapter.EvalController required a bean of type 'com.example.demo.adapter.KometRepository' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.demo.adapter.KometRepository' in your configuration.
What do I miss?
答案1
得分: 0
我通过在“Abrechnungsdaten”类上添加注解“@Table("THETABLE")”来使其工作。记录应该以相同的方式工作。
无论如何,我在“JdbcRepositoriesAutoConfiguration”中找到了提示。它只对带有“org.springframework.data.relational.core.mapping.Table”注解的类生效。
当你只有一个存储库(例如JDBC存储库)并且假定要使用它时,Spring Boot似乎不太严格。
另一方面,当你有多个选项时,你需要告诉Spring Boot实体基于一个关系表。
英文:
I made it work by adding the annotation @Table("THETABLE")
to the Abrechnungsdaten
class. A record should work in the same way.
Anyways, I found the hint in JdbcRepositoriesAutoConfiguration
. It only gets active for classes annotated with org.springframework.data.relational.core.mapping.Table
.
Spring boot seems to be less strict when you only have a single repository (e.g. the JDBC-repository) in place and then assumes that you want to use that.
On the other hand, when you have multiple options, you need to 'tell' Spring Boot that the entity is based on a relational table.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论