【问题标题】:CrudRepository findById dont return java.util. OptionalCrudRepository findById 不返回 java.util。可选的
【发布时间】:2019-01-15 18:28:28
【问题描述】:

公共接口 LmsRepository 扩展 CrudRepository 我没有获取单个计数的 findOne 方法,所以当我使用 findById 时出现此异常。“在类型 [java.util.Optional] 上找不到属性 [id]”我该如何解决这个问题?

这是我的 CrudRepo

@Repository
public interface LmsRepository extends CrudRepository<Book, Long> {


}

实体文件

@Entity(name="lms_tbl")
public class Book {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column(name="book_name")
private String bookName;

private String author;

@Column(name="purchase_date")
@Temporal(TemporalType.DATE)
private Date purchaseDate;

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

and other....

服务文件

@Service
public class LmsService {

@Autowired
private LmsRepository lmsRepository;

public Collection<Book> findAllBooks(){
    ArrayList<Book> books = new ArrayList<Book>();
    for (Book book : lmsRepository.findAll()) {
        books.add(book);
    }

    return books;
}

public void deleteBook(long id) {

    lmsRepository.deleteById(id);
}

public Optional<Book> findById(Long id) {

    return lmsRepository.findById(id);
}

}

控制器文件

@Controller
public class MainController {

@Autowired
private LmsService lmsService;


@GetMapping("/")
public String index(HttpServletRequest req) {
    req.setAttribute("books", lmsService.findAllBooks());
    req.setAttribute("mode","BOOK_VIEW");
    return "index";
}

@GetMapping("/updateBook")
public String index(@RequestParam Long id,HttpServletRequest req) {
    req.setAttribute("book", lmsService.findById(id));
    req.setAttribute("mode","BOOK_EDIT");
    return "index";
}

}

我尝试在 CrudRepo 中添加新方法,但它不起作用。

【问题讨论】:

标签: java spring-boot spring-data-jpa


【解决方案1】:

在你的服务类中改变这个

public Optional<Book> findById(Long id) {
    return lmsRepository.findById(id);
}

到这里

public Book findById(Long id) {
    return lmsRepository.findById(id).get();
}

说明:Optional 是一个包装类,它可能包含也可能不包含非空值。你得到这个错误是因为你试图在模型中插入Optional,而不是Book。由于Optional 不包含任何id 字段,您会收到错误消息。 Optional 用于在您有一个您不希望它为空的空对象时具有引发异常的默认值。例如,您可以创建一个在 null 可选的情况下自动抛出异常。例如,您可以通过以下方式升级您的服务:

public Book findById(Long id) {
    return lmsRepository.findById(id).orElseThrow(RuntimeException::new);
}

这将在BookOptional 中为空的任何时候抛出RuntimeException,或者将返回Book 类的值。

一个更优雅的解决方案如下:

public Book findById(Long id) {
    return lmsRepository.findById(id).orElseThrow(NotFoundException::new);
}

拥有:

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
}

以这种方式,当可选项包含Book 时,它会返回给控制器并插入到模型中。如果Optional 包含一个空值,那么NotFoundException 将被抛出,它不需要被捕获,并且会被映射到404 HTTP 错误。

【讨论】:

    【解决方案2】:

    您可以在存储库中创建自己的方法。

    LmsRepository<CustomClass> extends CrudRepository<CustomClass> {
      Optional<CustomClass> findById(int id);
    }
    

    【讨论】:

    • 实际上麻烦的是我无法在 jsp 中显示“可选”结果。我正在使用 HttpServletRequest setAttribute 向 jsp 发送变量
    • @ZülküfADSIZ 您必须使用.get().else 来提取图书实体,然后使用提取的图书设置属性。
    【解决方案3】:

    在您的实体中,您在 id 上声明 @Id,因此 findById 遵循此(主键)数据类型,即存储库管理的实体的 id。

    【讨论】:

    【解决方案4】:

    只需将.get() 放在lmsRepository.findById(id).get() 之后;

    .get() 解析并将返回从数据库中捕获的 [lms 对象]

    无需重写、实施等等。

    【讨论】:

      【解决方案5】:

      您可以在界面中添加方法

      @Repository
      public interface LmsRepository extends CrudRepository<Book, Long> {
      Optional<Book> findById(Long id);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-08
        • 1970-01-01
        • 2018-08-29
        • 2021-12-13
        • 1970-01-01
        • 2022-10-04
        • 2019-02-08
        • 1970-01-01
        相关资源
        最近更新 更多