JpaRepository findAll返回空List

时间:2019-05-30 02:59:40

标签: java maven spring-boot httprequest

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);
}

在执行更新查询后,我的问题第一次出现(或者我认为),但是我尝试运行一个我知道它可以在另一台计算机上运行但无法正常运行的版本。

2 个答案:

答案 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) 解决了该问题。