存储库未启动
Repository Not Being Initiated
我在尝试将我的存储库启动从我的应用程序 class 移动到配置 class 时遇到错误。这看起来很奇怪,因为 urlRepository.save 调用没有抛出,而 urlRepository.findAll() 得到一个空值。我在这里做错了什么?
之前(工作正常 - 使用预加载 URL 打印到控制台)
@SpringBootApplication
public class UrlShortenerApplication implements CommandLineRunner {
@Autowired
private UrlRepository urlRepository = new MongoUrlRepository();
public static void main(String[] args) {
SpringApplication.run(UrlShortenerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
String shortlinkStub = "short.li/";
String cascadeDishPods = "https://www.amazon.com/gp/product/B07CTQ8THP/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1";
String flipFlops = "https://www.amazon.com/gp/product/B0013MWDO0/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1";
urlRepository.save(new ShortUrl(shortlinkStub + "flipflops", flipFlops));
urlRepository.findAll().forEach(shortUrl -> System.out.println("Preloaded " + shortUrl));
}
}
之后(repository.findAll() 的空指针异常)
ShortenerConfig.java
@Configuration
public class ShortenerConfig {
public static UrlRepository urlRepository = new MongoUrlRepository();
@Bean("urlRepo")
public UrlRepository urlRepo() {
return urlRepository;
}
}
UrlShortenerApplication.java
@SpringBootApplication
public class UrlShortenerApplication implements CommandLineRunner {
@Autowired
@Qualifier("urlRepo")
private UrlRepository urlRepository;
public static void main(String[] args) {
SpringApplication.run(UrlShortenerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
String shortlinkStub = "short.li/";
String cascadeDishPods = "https://www.amazon.com/gp/product/B07CTQ8THP/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1";
String flipFlops = "https://www.amazon.com/gp/product/B0013MWDO0/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1";
urlRepository.save(new ShortUrl(shortlinkStub + "flipflops", flipFlops));
urlRepository.findAll().forEach(shortUrl -> System.out.println("Preloaded " + shortUrl));
}
}
最后一行抛出一个空指针异常,我不知道为什么!
堆栈跟踪
第 22 行指的是“运行”,第 35 行指的是 reponsitory.findAll()
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-06-12 10:48:25.813 ERROR 75530 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at com.example.urlshortener.UrlShortenerApplication.main(UrlShortenerApplication.java:22) ~[main/:na]
Caused by: java.lang.NullPointerException: null
at com.example.urlshortener.UrlShortenerApplication.run(UrlShortenerApplication.java:35) ~[main/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
... 5 common frames omitted
2020-06-12 10:48:25.843 INFO 75530 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
存储库接口和Class(两种情况)
public interface UrlRepository extends MongoRepository<ShortUrl, Long> {
public ShortUrl findByShortUrl(String shortUrl);
public List<ShortUrl> findByLongUrl(String longUrl);
}
public class MongoUrlRepository implements UrlRepository {
@Override
public ShortUrl findByShortUrl(String shortUrl) {
return null;
}
@Override
public List<ShortUrl> findByLongUrl(String longUrl) {
return null;
}
.....
MongoUrlRepository 应该是一个接口,这就是 Spring 可以自动管理它的 crud 实现的方式。由于您将其声明为 class,因此您基本上将内置查找器方法覆盖为 return null,这就是您的 NPE 的来源。
参见 spring.io 中的示例:
https://spring.io/guides/gs/accessing-data-mongodb/
为什么它在第一种情况下有效:
@Autowired
private UrlRepository urlRepository = new MongoUrlRepository();
您实例化了一个 MongoUrlRepository,但是该对象将在依赖项注入期间被替换,并且由于您没有指定限定符 spring 将构建一个托管的 MongoRepository bean(基于您的 UrlRepository 接口)并忽略您的 MongoUrlRepository class.
我在尝试将我的存储库启动从我的应用程序 class 移动到配置 class 时遇到错误。这看起来很奇怪,因为 urlRepository.save 调用没有抛出,而 urlRepository.findAll() 得到一个空值。我在这里做错了什么?
之前(工作正常 - 使用预加载 URL 打印到控制台)
@SpringBootApplication
public class UrlShortenerApplication implements CommandLineRunner {
@Autowired
private UrlRepository urlRepository = new MongoUrlRepository();
public static void main(String[] args) {
SpringApplication.run(UrlShortenerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
String shortlinkStub = "short.li/";
String cascadeDishPods = "https://www.amazon.com/gp/product/B07CTQ8THP/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1";
String flipFlops = "https://www.amazon.com/gp/product/B0013MWDO0/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1";
urlRepository.save(new ShortUrl(shortlinkStub + "flipflops", flipFlops));
urlRepository.findAll().forEach(shortUrl -> System.out.println("Preloaded " + shortUrl));
}
}
之后(repository.findAll() 的空指针异常)
ShortenerConfig.java
@Configuration
public class ShortenerConfig {
public static UrlRepository urlRepository = new MongoUrlRepository();
@Bean("urlRepo")
public UrlRepository urlRepo() {
return urlRepository;
}
}
UrlShortenerApplication.java
@SpringBootApplication
public class UrlShortenerApplication implements CommandLineRunner {
@Autowired
@Qualifier("urlRepo")
private UrlRepository urlRepository;
public static void main(String[] args) {
SpringApplication.run(UrlShortenerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
String shortlinkStub = "short.li/";
String cascadeDishPods = "https://www.amazon.com/gp/product/B07CTQ8THP/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1";
String flipFlops = "https://www.amazon.com/gp/product/B0013MWDO0/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1";
urlRepository.save(new ShortUrl(shortlinkStub + "flipflops", flipFlops));
urlRepository.findAll().forEach(shortUrl -> System.out.println("Preloaded " + shortUrl));
}
}
最后一行抛出一个空指针异常,我不知道为什么!
堆栈跟踪
第 22 行指的是“运行”,第 35 行指的是 reponsitory.findAll()
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-06-12 10:48:25.813 ERROR 75530 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at com.example.urlshortener.UrlShortenerApplication.main(UrlShortenerApplication.java:22) ~[main/:na]
Caused by: java.lang.NullPointerException: null
at com.example.urlshortener.UrlShortenerApplication.run(UrlShortenerApplication.java:35) ~[main/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) ~[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
... 5 common frames omitted
2020-06-12 10:48:25.843 INFO 75530 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
存储库接口和Class(两种情况)
public interface UrlRepository extends MongoRepository<ShortUrl, Long> {
public ShortUrl findByShortUrl(String shortUrl);
public List<ShortUrl> findByLongUrl(String longUrl);
}
public class MongoUrlRepository implements UrlRepository {
@Override
public ShortUrl findByShortUrl(String shortUrl) {
return null;
}
@Override
public List<ShortUrl> findByLongUrl(String longUrl) {
return null;
}
.....
MongoUrlRepository 应该是一个接口,这就是 Spring 可以自动管理它的 crud 实现的方式。由于您将其声明为 class,因此您基本上将内置查找器方法覆盖为 return null,这就是您的 NPE 的来源。
参见 spring.io 中的示例: https://spring.io/guides/gs/accessing-data-mongodb/
为什么它在第一种情况下有效:
@Autowired
private UrlRepository urlRepository = new MongoUrlRepository();
您实例化了一个 MongoUrlRepository,但是该对象将在依赖项注入期间被替换,并且由于您没有指定限定符 spring 将构建一个托管的 MongoRepository bean(基于您的 UrlRepository 接口)并忽略您的 MongoUrlRepository class.