初学SpringBoot2.x整合Spring Data JPA的坑。

初学SpringBoot2.x整合Spring Data JPA的坑。

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field ‘id’ cannot be found on object of type ‘java.util.Optional’ - maybe not public or not valid?

不知道是不是有小伙伴本我一样会出现这样的报错信息呢。
最近在初学SpringBoot2.x整合Spring Data JPA的坑。
先说一下为何会遇到这问题吧,在做一个博客项目,最开始就有springboot整合spring data jpa以简化相关的数据操作。

/**
 * user 实体
 */
@Entity  //标注为实体
public class User implements Serializable {

    @Id  //标注为主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) //将主键设置成自增长
    private Long id;
    private String name;
    private String email;
    private int age;
    private String sex;

    //JPA的规范要求无参构造函数,设为protected防止直接调用
    protected User() {
    }

    public User( String name, String email, int age, String sex) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.sex = sex;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override   //override:重写
    public String toString() {
        return String.format("User[id=%d,name='%s',email='%s',age='%d',sex='%s']",id,name,email,age,sex);
    }
}

这是通过jpa注解的实体,之后会改变repository层。只需要集成接口即可。

/**
 * User资源库接口
 */
public interface UserRepository extends CrudRepository<User,Long> {
}

正常我们是需要在这写具体的增删改查的方法之后再写具体的实现类,实现此接口后就不需要实现类了,这个接口里面都是有的。(但是此接口是没有update和insert方法的,这点得注意。)
不过之后写完后端后进行修改操作的时候就出错了。
这是我的修改操作:初学SpringBoot2.x整合Spring Data JPA的坑。_第1张图片
在这里说明一下,我跟的教程里面所引入的JPA版本较低,教程里面使用的是findOne(Id)来对单个用户进行查询后修改的,我使用的是springboot2.2所引入的JPA,所以是没有findOne()这个方法的,而是FindById(Id)
前端代码:

用户ID:<P><span th:text="${userModel.user.id}"></span></P>

此时运行就会报这个错:
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field ‘id’ cannot be found on object of type ‘java.util.Optional’ - maybe not public or not valid?
(无法在类型为“java.util.Optional”的对象上找到属性或字段“id”。可选的——可能不是公共的或无效的?)
可能有的小伙子跟我一样对这个Optional到底是个什么鬼,我的实体呢,之后Debug发现端倪:
初学SpringBoot2.x整合Spring Data JPA的坑。_第2张图片

http://localhost:8989/users/1

首先我们的传值是没有问题的,也有查到值但是发现是被Optional所包裹的,之后去看方法返回值确实不是User而是Optional;因为教程里面使用findOne()查询出来直接返回的直接是实体对象,就在想为啥到我和属性都拿不到了呢。之后一看发现findById()这个方法返回的是Optional类型的,并不是直接的实体对象,所以不能直接调用user的属性,运行时前端就会出错了。
那既然这样就把我们的User拿出来再取对应属性就行了呀。这引出大佬:
https://blog.csdn.net/Anbernet/article/details/80851573(讲的个人觉得讲Optional讲的很细。)
大概了解之后知道Optional具体的get()方法可以获得里面的具体泛型,之后我们的实体有具体的Getter和Setter方法我们用getId()就可以拿到user.id了。希望帮助到跟我一样的小白初学者吧。
最后给大家分享一个我学习的小技巧,我们电脑装上有道,运行后对于看不懂啥意思的报错信息选中之后就退弹出一个小的搜索标志,之后鼠标放上去就会显示翻译了,单个单词的话不用选中鼠标直接放上去就会有具体单词释义了。

初学SpringBoot2.x整合Spring Data JPA的坑。_第3张图片

你可能感兴趣的:(springboot,JPA)