Как правильно объединить таблицы в Spring Boot - PullRequest
1 голос
/ 30 мая 2019

У меня есть пользователь, и у пользователя есть расходы. В таблице расходов я хочу иметь идентификатор расходов, пользователя, который сделал расходы и сумму расходов. В таблице пользователей я хочу указать идентификатор пользователя, его имя пользователя, его текущий баланс и список всех расходов, которые он сделал.

Я хочу присоединиться к этим 2, но я не знаю, как правильно ссылаться на пользователя, поэтому пользовательская форма Класс расходов всегда нулевой.

Сначала я отправляю запрос на создание пользователя:

{
    "username":"abcd",
    "balance":"100"
}

тогда я хочу создать счет, но здесь я не уверен, как правильно отправить пользователя:

{
    "username":"abcd",
    "id":"1",
    "balance":"100",
    "amount":"20"
}

и это не работает, тогда я попытался так:

{
    "User":{
    "username":"abcd",
    "id":"1",
    "balance":"100"
    },
    "amount":"20"
}

и это тоже не сработало.

Это класс пользователя:

@Entity
@Table(name = "Users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotBlank(message = "Username is mandatory")
    private String username;
    private Double balance = 0.0;

    @OneToMany(mappedBy = "user")
    private List<Expense> expenses;
    ...

Я убрал геттеры и сеттеры отсюда.

Вот класс расходов:

@Entity
@Table(name = "Expenses")
public class Expense {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    private Double amount;
    ...

Для экономии расходов я использую .save() из JpaRepository<Expense, Long> и для извлечения всего, что я использую .findAll().

Результат всегда один и тот же: получить за все расходы дает

{
        "id": 1,
        "user": null,
        "amount": 20
}

и получить для всех пользователей дает

{
        "id": 1,
        "username": "abcd",
        "balance": 100,
        "expenses": []
}

Теперь я не уверен, правильно ли я отправляю запросы, или не присоединяюсь к таблицам, или и то, и другое.

РЕДАКТИРОВАТЬ: здесь ExpenseController:

@RestController
public class ExpenseController {

    @Autowired
    IExpenseService expenseService;

    @GetMapping("/expenses")
    public List<Expense> findExpenses() {
        return expenseService.findAll();
    }

    @PostMapping("/expenses")
    public void createNewExpense(@RequestBody Expense expense) {
        expenseService.createNewExpense(expense);
    }
}

createNewUser(...) от ExpenseService

@Override
    public void createNewExpense(Expense expense) {
        repository.save(expense);
    }

и ExpenseRepository:

@Repository
public interface ExpenseRepository extends JpaRepository<Expense, Long> {
}

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());
            response.put("expenses", currentUser.getExpenses());
            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);
    }
}

остальная часть модели User аналогична модели Expense.

1 Ответ

1 голос
/ 30 мая 2019

Попробуйте отправить запрос с этой полезной нагрузкой (поле «пользователь» начинается с маленькой буквы), и я думаю, что поля «id» в объекте пользователя должно быть достаточно

  { 
   "user":{
     "username":"abcd",
     "id":"1",
     "balance":"100"
    },
    "amount":"20"
  }

РЕДАКТИРОВАТЬ: Кроме того, вам необходимо добавить @JsonIgnoreProperties ("расходы") к вашей сущности расходов, чтобы предотвратить рекурсивное чтение Джексона json

@Entity
@Table(name = "Expenses")
public class Expense {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @JsonIgnoreProperties("expenses")
  @ManyToOne
  @JoinColumn(name = "user_id")
  private User user;

  private Double amount;
.....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...