findAll()
中的 JpaRepository
方法返回空值,但正确数量的空值
我正在使用h2数据库,一切正常,直到某个未知时刻。 http://localhost:8080/users
处的简单GET返回{} x先前添加到数据库中的用户数。我尝试实现一种方法,该方法将根据用户名返回ID,并且效果很好。
这是我的User.java
:
@Entity
@Table(name = "Users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username")
@NotBlank(message = "Username is mandatory")
@Size(min = 1, max = 20, message = "Username must be less than 20 characters long")
private String username;
@Column(name = "balance")
private Double balance = 0.0;
Long getId() {
return id;
}
void setId(Long id) {
this.id = id;
}
String getUsername() {
return username;
}
void setUsername(String username) {
this.username = username;
}
Double getBalance() {
return balance;
}
void setBalance(Double balance) {
this.balance = balance;
}
}
这里是UserService
,它实现了IUserService
中的方法:
@Service
public class UserService implements IUserService {
@Autowired
private UserRepository repository;
@Override
public void createNewUser(User user) {
repository.save(user);
}
@Override
public List<User> findAll() {
return repository.findAll();
}
@Override
public Long findByUsername(String username) {
return repository.findByUsername(username);
}
@Override
public User findById(Long id) {
return repository.findById(id).orElse(null);
}
@Override
public boolean checkIfUsernameIsTaken(User user) {
return repository.findByUsername(user.getUsername()) != null;
}
@Override
public void deleteUser(Long id) {
repository.deleteById(id);
}
@Override
public void updateBalance(Long id, Double balance) {
repository.updateBalance(id, balance);
}
}
我尝试了带@Column
注释和不带注释的情况,但似乎没有任何作用。
如果我仅通过createNewuser()
添加了一个用户,则从Postman获得的输出为[{}],如果我添加了两个用户,则为[{},{}]。我不明白是什么破坏了findAll()
方法。
P.S。 updateBalance()
也不起作用,但这是另外一段时间了。
编辑:您要求UserController
的一些内容:
@RestController
public class UserController {
@Autowired
IUserService userService;
@GetMapping("/users")
public List<User> findUsers() {
return userService.findAll();
}
@GetMapping("/users/{id}")
public User findUserById(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping("/users")
public ResponseEntity<Object> createUser(@RequestBody User user) {
if (userService.checkIfUsernameIsTaken(user)) {
Map<String, Object> response = new HashMap<>();
response.put("status", HttpStatus.NOT_ACCEPTABLE);
response.put("errors", "Username is already taken");
response.put("timestamp", new Date());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
} else {
userService.createNewUser(user);
User currentUser = userService.findById(userService.findByUsername(user.getUsername()));
Map<String, Object> response = new HashMap<>();
response.put("id", currentUser.getId());
response.put("username", currentUser.getUsername());
response.put("balance", currentUser.getBalance());
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
@PutMapping("/users/{id}/{balance}")
public void updateBalance(@PathVariable Long id, @PathVariable Double balance) {
userService.updateBalance(id, balance);
}
}
和UserRepository
:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT id FROM User WHERE username = ?1")
Long findByUsername(String username);
@Transactional
@Modifying
@Query("UPDATE User SET balance = ?2 WHERE id = ?1")
void updateBalance(Long id, Double balance);
}
在执行更新查询后,我的问题第一次出现(或者我认为),但是我尝试运行一个我知道它可以在另一台计算机上运行但无法正常运行的版本。
答案 0 :(得分:1)
问题在于您的属性不是可变。您已经公开了getter和setter,但未指定访问级别,并且默认情况下它们不是 public ,因此hibernate无法看到它们,因此无法使用数据库返回的记录填充您的实体。将它们设为公开可以解决该问题。
答案 1 :(得分:0)
虽然上面的答案解决了这个问题,但我遇到了类似的情况,set a "--------------------------------------------------------------------------------
Proto Source Address Pkt-Cnt Start
Destination Address Byte-Cnt
--------------------------------------------------------------------------------
UDP 150.1.1.2 25 05/24/2021 07:07:29
150.2.1.2 1150
--------------------------------------------------------------------------------"
set b "UDP"
regexp "$b\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)" $a match data1 data2 data3 data4 data5 data6
puts "$data1, $data2, $data3, $data4, $data5, $data6"
# 150.1.1.2, 25, 05/24/2021, 07:07:29, 150.2.1.2, 1150
会返回结果,而 repository.findById(id)
会返回空。
事实证明,我用 repository.findAll()
包装了调用方方法,该方法将写入然后读取所有记录:
@Transactional(readOnly = true)
将 @Override
@Transactional(readOnly = true)
public List<Object> writeThenReadAll(...){
repository.save(...);
...
Object byId = repository.findById(1L).get(); //not null
List<Object> all = repository.findAll(); //returns empty
return all;
}
更改为 @Transactional(readOnly = true)
解决了该问题。