Spring Data JPA: использование объекта, полученного с помощью `JpaRepository.getOne (id)` - PullRequest
1 голос
/ 19 мая 2019

В моем приложении Spring Boot, созданном с помощью JHipster (v6.0.1) Kotlin blueprint (v0.8.0), у меня есть следующий обработчик POST-запроса

    @PostMapping("/book")
    fun createBook(@RequestBody createBookVM: CreateBookVM): ResponseEntity<Book> {
        val author = authorRepository.getOne(createBookVM.authorId)
        val userLogin = SecurityUtils.getCurrentUserLogin().orElseThrow { RuntimeException("User not logged in") }
        val user = userRepository.findOneByLogin(userLogin).orElseThrow { RuntimeException("IMPOSSIBLE: user does not exist in DB") }
        val book= Book()
        book.author = author // FIXME
        book.user = user
        log.debug("Author object with id : {}", author.id) // THIS WORKS
        val result = bookRepository.save(book)
        return ResponseEntity.created(URI("/api/books/" + result.id))
            .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.id.toString()))
            .body(result)
    }

Проблема в том, что author не добавляется к book (book.author будет null). Тем не менее, я могу получить доступ к значениям author, как показано в операторе регистрации. Добавление user к book также работает нормально.

Полагаю, проблема в том, что authorRepository.getOne(createBookVM.authorId) возвращает прокси-объект, а не экземпляр Author, но я не знаю, как справиться с этой ситуацией.

1 Ответ

3 голосов
/ 19 мая 2019

Вместо использования authorRepository.getOne(createBookVM.binId) используйте authorRepository.findById(createBookVM.binId).

T getOne(ID id) возвращает ссылку, а не сущность.

/**
 * Returns a reference to the entity with the given identifier.
 *
 * @param id must not be {@literal null}.
 * @return a reference to the entity with the given identifier.
 * @see EntityManager#getReference(Class, Object)
 * @throws javax.persistence.EntityNotFoundException if no entity exists for given {@code id}.
 */
T getOne(ID id);

Optional<T> findById(ID id) возвращает сущность.

/**
 * Retrieves an entity by its id.
 *
 * @param id must not be {@literal null}.
 * @return the entity with the given id or {@literal Optional#empty()} if none found
 * @throws IllegalArgumentException if {@code id} is {@literal null}.
 */
Optional<T> findById(ID id);

Также вы можете использовать authorRepository.findOne(createBookVM.binId) для более старых версий, чем jpa 2.xx:

/**
 * Retrieves an entity by its id.
 * 
 * @param id must not be {@literal null}.
 * @return the entity with the given id or {@literal null} if none found
 * @throws IllegalArgumentException if {@code id} is {@literal null}
 */
T findOne(ID id);
...