Spring JPA поле денормализованного счетчика один ко многим

У меня есть две сущности, Книги и Комментарии, в отношениях один ко многим (одна книга может иметь много комментариев). Я хочу быть в состоянии перечислить книги и количество комментариев о книге. Я хочу, чтобы он был денормализован, то есть у сущности books будет счетчик с количеством комментариев к этой книге, и он будет обновляться каждый раз при вводе комментария (просто игра с концепцией, нет необходимости обсуждать необходимость денормализации здесь).).

Я думаю (поправьте меня, если я ошибаюсь) это можно легко сделать с помощью триггера в базе данных (когда создается новый комментарий, обновите счетчик в таблице книг до соответствующего bookId), но ради обучения я хочу сделать это через JPA, если это имеет смысл.

Что я до сих пор: // опущены некоторые аннотации, просто общая информация

Бокс сущность:

@Entity 
public class Books {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;
    private String author;
    private Long numComments;

  // getters and setters...
}

Комментарии объекта:

@Entity
public class Comments {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String comment;
    private Long authorId;
    private Long bookId;

  // getters and setters...
}

Репозиторий книг: я добавил сюда запрос для выполнения обновления

/**
 * Spring Data JPA repository for the Books entity.
 */
public interface BooksRepository extends JpaRepository<Books,Long>         {
@Modifying
@Query("UPDATE Books v SET v.numComments = v.numComments + 1 WHERE v.id = :bookId")
int updateCounter(@Param("bookId")Long bookId);

}

А теперь вопрос: что дальше? Я думаю, что могу поместить обновление сущности Books, аннотирующее с помощью @PostPersist метод сущности Comments, но пока я потерпел неудачу. Я могу представить что-то вроде этого:

    @PostPersist  //This function in the entity Comments
    protected void updateBooks() {
        //Likely some call to the repository here that updates the count
        //   in books the info we have from current entity.
    }

Есть идеи, как это сделать? Некоторые лучшие практики об этом виде денормализации в JPA? Лучше использовать триггеры базы данных?

1 ответ

Весной не управлял вашими сущностями, и ваша идея возможна, но вы должны ввести BooksRepository в энтти класс тогда останься у тебя нольпоинтерекс, потому что весной не успел энтай классы, причина твоя BooksRepository не инициализировано, попробуйте также прочитать этот пост Инъекция Бина в класс сущности JPA @Entity и anotate @Configurable после

попробуй это

@PostPersist 
protected void updateBooks(Comments comment) {

    int totalComment = BooksRepository.updateCounter(comment.getBookId());

    System.out.println(totalComment); // see totalComment in console
}

но хороший упор в классах обслуживания после звонка updateCounter когда вставить комментарий

пример в вашем CommendService: когда вы пытаетесь вставить вставку Commend после вызова вашего updateCounter

    if(comment.getBookId() != null) //Simple Control
     {

        CommentRepository.save(comment);
        BooksRepository.updateCounter(comment.getBookId());
    }
Другие вопросы по тегам