【问题标题】:I can't use findOne() method in my code我不能在我的代码中使用 findOne() 方法
【发布时间】:2018-08-19 19:27:39
【问题描述】:

我的应用程序出错,因为我使用了 findOne() 方法。下面是我的简单代码。在 User 类中,我的 id 是 String email,这就是我试图在我的类 UserService 中使用的 id,如下所示:

public User findUser(String email){
    return userRepository.findOne(email);
}

但我有这个错误:

接口 org.springframework.data.repository.query.QueryByExampleExecutor 中的方法 findOne 不能应用于给定类型;
必需:org.springframework.data.domain.Example
找到:java.lang.String
原因:无法推断类型变量 S (参数不匹配;java.lang.String 无法转换为 org.springframework.data.domain.Example)

用户类别:

@Entity
@Data
@Table(name = "User")
public class User {
    @Id
    @Email
    @NotEmpty
    @Column(unique = true)
    private String email;

    @NotEmpty
    private String name;

    @NotEmpty
    @Size(min = 5)
    private String password;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Task> tasks;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "USER_ROLE", joinColumns = {
        @JoinColumn(name = "USER_EMAIL", referencedColumnName = "email")
    }, inverseJoinColumns = {@JoinColumn(name = "ROLE_NAME", referencedColumnName = "name")})
    private List<Role> roles;
}

和用户存储库:

public interface UserRepository extends JpaRepository<User, String> {
}

【问题讨论】:

  • 异常引用org.springframework.data.domain.Example 的事实让我觉得你在你的一些示例代码中留下了一些东西。环顾四周并仔细检查您的配置。搜索单词Example,看看你找到了什么
  • CrudRepository 中不再有 findOne(ID) 方法。使用 findById(ID)。阅读 javadoc。

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


【解决方案1】:

JpaRepository 中的 findOne 方法定义为:

<S extends T> Optional<S> findOne(Example<S> example)

Reference

你正在传递一个字符串作为参数。 如果要通过 User.email 查找,方法必须定义为:

User findOneByEmail (String email);

这个机制在query creation document中有解释

【讨论】:

    【解决方案2】:

    如果您只想按 id 进行搜索,请使用 findByIdgetOne 而不是 findOne

    public User findUser(String email){
        return userRepository.getOne(email); // throws when not found or
                                             // eventually when accessing one of its properties
                                             // depending on the JPA implementation
    }
    
    public User findUser(String email){
        Optional<User> optUser = userRepository.findById(email); // returns java8 optional
        if (optUser.isPresent()) {
            return optUser.get();
        } else {
            // handle not found, return null or throw
        }
    }
    

    函数findOne()接收一个Example&lt;S&gt;,该方法用于通过示例查找,因此需要提供示例对象和要检查的字段。

    您可以通过示例找到如何使用查找。

    https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example.matchers

    但它基本上是这样的。

    User user = new User();                          
    person.setName("Dave");                           
    
    ExampleMatcher matcher = ExampleMatcher.matching()     
        .withIgnorePaths("name")                         
        .withIncludeNullValues()                             
        .withStringMatcherEnding();
    
    Example<User> example = Example.of(user, matcher); 
    

    【讨论】:

    • getOne() 在找不到时不会抛出。相反,它返回一个未初始化的代理,假设实体存在。
    • “抛出:javax.persistence.EntityNotFoundException - 如果给定 id 不存在实体。”至少在当前文档中是这样说的。
    • 允许这样做,但通常不会发生。 getOne() 只是调用 EntityManager.getReference()。 docs.oracle.com/javaee/7/api/javax/persistence/…
    • 很高兴知道这取决于 JPA 实现。因此,该异常是有保证的,但不是必须在那个时刻抛出的,至少应该在尝试访问一个属性时抛出该异常吗?
    【解决方案3】:

    我有类似的东西。这是因为您使用的是较新的版本。

    您可以通过以下方式修复它:

    return userRepository.findById(email).orElse(null);
    

    【讨论】:

      猜你喜欢
      • 2018-09-08
      • 2020-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      相关资源
      最近更新 更多