【问题标题】:Property or field 'name' cannot be found on object of type 'java.util.Optional' - maybe not public or not valid?在“java.util.Optional”类型的对象上找不到属性或字段“名称” - 可能不是公共的或无效的?
【发布时间】:2018-06-18 07:42:21
【问题描述】:

我想在单击房间名称时显示房间详细信息。但我有一个问题,我不知道为什么。我使用 Spring MVC、Spring Boot、Spring Data 和 Thymeleaf

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

当我使用 Spring Data findById() 时,我认为问题在于 Optional in Service 这是我的代码

房间模型

@Entity
@Table(name ="room")
public class Room implements Serializable {
 private static final long serialVersionUID = 1L;
 @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID_room", nullable = false)
    private String id;


    @Column(name = "name_room", nullable = false)
    private String name;


    @Column(name = "Description")
    private String describe;

    @Column(name = "ID_status")
    private String status;

    @Column(name = "room_image")
    private String image;

    public Room() {
        super();
    }

    public Room(String id, String name, String describe, String status,String image) {
        super();
        this.id = id;
        this.name = name;
        this.describe = describe;
        this.status = status;
        this.image = image;

    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getDescribe() {
        return describe;
    }

    public void setDescribe(String describe) {
        this.describe = describe;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }


}

客房服务

public interface RoomService {


Optional<Room> findOne(String id);


}

客房服务工具

public class RoomServiceImpl implements RoomService {
@Autowired
private RoomRepository roomRepository;

@Override
public Optional<Room> findOne(String id) {

    return roomRepository.findById(id);
}

}

RomController

@GetMapping("/room/{id}/detail")
public String detail(@PathVariable String id, Model model) {
    model.addAttribute("room", romService.findOne(id));
    return "roomDetail";
}

roomDetail.html

<div class="col-md-7 single-top-in">
                    <div class="single-para">
                        <h4><tr th:text="${room.name}"></h4>
                        <div class="para-grid">
                            <span  class="add-to">$32.8</span>
                            <a href="#" class="hvr-shutter-in-vertical cart-to">Add to Cart</a>                 
                            <div class="clearfix"></div>
                         </div>
                        <h5>100 items in stock</h5>

                        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>

【问题讨论】:

  • 请提供Room类的代码
  • 不要在视图中直接使用db实体
  • 我编辑了房间模型。请检查帮助我
  • 在模型属性中传递model.addAttribute("room", romService.findOne(id).get()); // 添加 .get 以便可以直接访问。

标签: java spring


【解决方案1】:

org.springframework.expression.spel.SpelEvaluationException: EL1008E: 在类型的对象上找不到属性或字段“名称” 'java.util.Optional' - 可能不公开或无效?

意味着 Spring 没有设法插入模板中使用的 name 属性:

  <h4><tr th:text="${room.name}"></h4>

这是预期的,因为您将 Optional&lt;Room&gt; 对象传递给 MVC 模型,而不是传递 Room 对象。
在将 Optional 中包含的对象添加到模型之前,您必须解包它。
例如:

romService.findOne(id).ifPresent(o -> model.addAttribute("room", o));

【讨论】:

  • 我必须做什么
  • 解开 Optional 中包含的对象,如我的示例所示。
  • 对不起,但我还是明白...什么是 varialbe "o"
  • 它是Room 对象,作为Optional.ifPresent() 中的参数提供。 o -&gt; model.addAttribute("room", o) 是一个 lambda 表达式。 ifPresent() 定义为 public void ifPresent(Consumer&lt;? super T&gt; consumer) {。在 Java 8 中,Consumer 等函数式接口可以替换为 lambda 表达式。
  • 非常感谢.. 虽然我不明白为什么 T.T
【解决方案2】:

一个例子:

 if( user.isPresent() ) {
            model.addAttribute("user", user.get());

Long userId = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
        Optional<User> user = userService.findById(userId);

        if( user.isPresent() ) {
            model.addAttribute("user", user.get());
}

【讨论】:

    【解决方案3】:

    我要提一件事,这是 thymeleaf 对嵌套字段/属性所期望的本机约定

    private FieldType fieldname;
    public FieldType getFieldname(){return this.fieldname;}
    public void setFieldname(FieldType ff){this.fieldname=ff;}
    

    请注意字段名称如何小写,但 getFieldname 的开头为“f”大写。对于二传手也是如此。

    如果你的班级有 getfieldname() 而没有 getFieldname(),你可能会遇到麻烦

    【讨论】:

      【解决方案4】:

      在我的情况下,csv 使用 \t 而不是逗号创建的错误。替换或使用 \t 分隔符解决了问题。

      【讨论】:

        【解决方案5】:

        始终检查实体的 getter 和 setter 方法。就我而言,我使用的是 getpatientId 而不是 getPatient。由于 Spring 会自动执行这些操作,因此它需要这些约定。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-13
          • 2018-11-20
          • 2020-09-22
          • 2016-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多