CrudRepository findById不返回java.util。可选的

时间:2018-08-08 13:06:02

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

公共接口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中添加新方法,但是它不起作用。

4 个答案:

答案 0 :(得分:1)

在您的服务类别中更改此内容

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

对此

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

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

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

只要RuntimeExceptionBook中为空,就会抛出Optional,或者将您退回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错误。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

无需重写,实施等。