【发布时间】:2019-05-31 16:53:21
【问题描述】:
我刚刚通过阅读Spring Boot in Action 一书开始学习 Spring Boot,并且我正在学习本书的示例,并尝试自己运行它们,但我有一个使用JpaRepository.findOne()的问题。
我已经在整个章节中寻找可能的不匹配项。但是,它只是不起作用。
该项目应该是一个简单的阅读列表。
代码如下:
读者@Entity:
package com.lixin.readinglist;
import org.springframework.data.annotation.Id;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.Entity;
import java.util.Collection;
import java.util.Collections;
/**
* @author lixin
*/
@Entity
public class Reader implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
private String username;
private String fullname;
private String password;
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singletonList(new SimpleGrantedAuthority("READER"));
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Jpa 接口:
package com.lixin.readinglist;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author lixin
*/
public interface ReaderRepository extends JpaRepository<Reader, String> {
}
安全配置:
package com.lixin.readinglist;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
/**
* @author lixin
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final ReaderRepository readerRepository;
@Autowired
public SecurityConfig(ReaderRepository readerRepository) {
this.readerRepository = readerRepository;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").access("hasRole('READER')")
.antMatchers("/**").permitAll()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService((UserDetailsService) username -> readerRepository.findOne(username));
}
}
我一直收到这个错误:
Error:(40, 86) java: method findOne in interface org.springframework.data.repository.query.QueryByExampleExecutor<T> cannot be applied to given types;
required: org.springframework.data.domain.Example<S>
found: java.lang.String
reason: cannot infer type-variable(s) S
(argument mismatch; java.lang.String cannot be converted to org.springframework.data.domain.Example<S>)
【问题讨论】:
-
您可能正在阅读一本旧书。在 Spring Data 的最新版本中,findOne() 已重命名为 findById()。它返回一个 Optional
,而不是 Reader 或 null。所以你需要修改代码。 -
还请注意,使用
String值作为主键通常是一种低效的选择,因为查找往往很慢。Long或UUID通常更好。 -
最后,查看 [Semantic Versioning](semver.org) 规范很有用。您的指南是为 Spring Data 1 编写的,而您正在使用 Spring Data 2,并且在主要版本之间可能会删除 API 组件——在这种情况下,
findOne方法已从CrudRepository中删除并替换为类似但不是相同的findById。 -
@JBNizet 感谢您的评论。我已经测试了 getOne() 方法,它抛出了你所说的确切错误。我已经更新了我的答案。作为一名本科生,很荣幸有你纠正我的错误,带领我走上正确的道路。感谢您的时间。
标签: java spring-boot spring-data-jpa