我在代码中找不到错误。寻求帮助。为什么方法findById()
不返回任何具有此ID的对象,而findAll()
却显示具有此ID的对象?
这是我的class User
:
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "login")
private String login;
@Column(name = "password")
private String password;
@JsonIgnore
@OneToOne(optional = false, mappedBy = "user")
private UserDetails userDetails;
}
我的class UserDetails
:
@Entity
@Table(name = "userdetails")
public class UserDetails {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "surname")
private String surname;
@OneToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User user;
}
我的控制器:
@RestController
public class AnotherUserController {
private final UserRepository userRepository;
@Autowired
public AnotherUserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/demo/{id}")
public User findById(@PathVariable("id") Long id) {
return userRepository.findById(id).orElseThrow(() -> new RuntimeException("user not found: " + id));
}
@PostMapping("/demo")
public User save(@RequestBody User user) {
return userRepository.save(user);
}
@GetMapping("/demo")
public Iterable<User> save() {
return userRepository.findAll();
}
}
我的存储库:
public interface UserRepository extends CrudRepository<User, Long> {
}
并记录:
2020-07-05 22:11:30.642 ERROR 13200 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
[Request processing failed; nested exception is java.lang.RuntimeException: user not found: 23] with root cause
java.lang.RuntimeException: user not found: 23
...
..
.
答案 0 :(得分:5)
好的,因此您具有@OneToOne(optional = false)
关系,并且正如您在评论中所说,此字段是个问题。按id查找不会返回用户,因为hibernate将inner join
到userdetails
,并且由于没有匹配的记录-没有结果。
因此解决方法很简单:如果您希望用户返回,即使他们与细节没有任何关系,也可以将关系标记为可选-@OneToOne(optional = true)
。然后,Hibernate将生成left outer join
而不是inner join
。
如果该关系不是可选的(从业务角度来看),则不应允许存在没有详细信息的用户的情况发生。最好在数据库级别进行检查(非空外键等)。
btw findAll
返回结果,因为它转换为select * from users
(无联接),然后根据需要延迟获取详细信息