我是Spring Data JPA的新手,我遇到了一些.新手问题。
我不能调用一个没有注解 @Controller 的持久化方法,或者 HTTP requests 的注解在我的类中。我知道类接口 CommandLineRunner 实现了一个方法 run,但是主代码需要留在方法 run 中,我想调用另一个类和自己的方法,就像一个facade行为。
型号:
package com.example.demo;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Expense {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String item;
private float amount;
public Expense () {
}
public Expense(String item, float amount) {
this.item = item;
this.amount = amount;
}
/* Getters and setters */
@Override
public String toString() {
return "Expense{" + "id=" + id + ", item=" + item + ", amount=" + amount + '}';
}
字符串
接口仓库
package com.example.demo;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface ExpenseRepository extends JpaRepository<Expense, Long>{
public List<Expense> findByItem (String item);
@Query("SELECT e FROM Expense e WHERE e.amount >= :amount")
public List<Expense> listItemsWithPriceOver(@Param("amount") float amount);
}
型
持久化类:
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
public class ExpansePersistence {
@Autowired
private ExpenseRepository repository;
public void expensePersistence() {
repository.save(new Expense("tomato", 10));
repository.save(new Expense("banana", 6));
repository.save(new Expense("apple", 12));
Iterable<Expense> iterator = repository.findAll();
System.out.println("List all: ");
iterator.forEach(item -> System.out.println(item.toString()));
}
}
型
主要方法
package com.example.demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
new ExpensePersistence().expensePersistence();
}
}
型
这里有一个类似的线程(How to call repository service in main class and use main arguments?),用户遇到了同样的问题和同样的输出错误,但是答案只解决了 *run * 方法,使用了接口 CommandLineRunner,但在run方法内部进行了编码。我想调用另一个方法。
运行的代码生成消息:
Caused by: java.lang.NullPointerException: Cannot invoke "com.example.demo.ExpenseRepository.findAll()" because "this.repository" is null
型
2条答案
按热度按时间mftmpeh81#
这是因为你的
ExpansePersistence
类的示例没有ExpenseRepository
类的注入示例- Spring IoC容器不能做到这一点。你应该声明ExpansePersistence
类的bean(例如使用@Service
annotation),让它实现CommandLineRunner
会更好。类似这样:字符串
然后
ExpansePersistence
和ExpenseRepository
都将由Spring IoC控制,bean注入将按预期工作。pgx2nnw82#
在您提供的示例中,
TestPersistence
是一个单元测试。这意味着它不能识别@Autowired
这样的注解(因为它没有spring上下文)。您需要一个@SpringBootTest
才能自动连接beans(在您的示例中是repository)。在这个tutorial中,您可以找到一个使用@SpringBootTest
测试repository的示例。祝你好运!