Spring JPA一对多非规范化计数字段

时间:2016-03-22 19:40:34

标签: spring jpa denormalization

我有两个实体,书籍和评论,一对多的关系(一本书可以有很多评论)。我希望能够列出有关书籍的书籍和评论数量。我想要它非规范化,这意味着书籍实体将有一个计数器,该书具有该书的评论数量,并且每次输入评论时它都会更新(只是在玩这个概念,不需要在这里讨论非规范化的需要) )。

我认为(如果我错了,请纠正我)这可以通过数据库中的触发器轻松完成(无论何时创建新注释,将books表中的计数器更新为相应的bookId),但为了学习我想通过JPA来做,如果有意义的话。

到目前为止://省略了一些注释,只是一般信息

Boks实体:

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

}

图书库:我在这里添加了一个执行更新的查询

    @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.
    }

现在的问题是:下一步是什么?我想我可以将Books实体的更新用@PostPersist注释为实体注释的方法,但到目前为止我还没有成功。我可以想象这样的事情:

public void testMedicalPartyTraffic(){
    doLogin(true);
    chooseDataset("Party");

    new Select(driver.findElement(By.id("searchId"))).selectByVisibleText("Medical Party Traffic");
    driver.findElement(By.id("chk_iiProviderId")).click();
    driver.findElement(By.id("chk_iiProviderId")).sendKeys(Keys.DELETE);
    ****driver.findElement(By.id("chk_iiProviderId")).sendKeys("HOSP_PROV000000002");****
    driver.findElement(By.id("btnSubmit")).click();

    WebElement table = waitForDataTable(1, 1, "dataTable");
    doubleClickByRowAndColumn(table, 1, 1);

    waitForText("_divScreenTitle", "Party");
}

有关如何做到这一点的任何想法?关于JPA中这种非规范化的一些最佳实践?最好使用数据库触发器吗?

1 个答案:

答案 0 :(得分:1)

春天没有管理你的实体类,你的想法是可能的,但是你必须在enttiy类中注入BooksRepository然后留在你得到Nullpointerexception,因为spring没有管理好的类,你的BooksRepository未初始化的原因,尝试在

之后阅读此帖Bean injection inside a 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中的示例:在致电updateCounter

后尝试插入推荐时
    if(comment.getBookId() != null) //Simple Control
     {

        CommentRepository.save(comment);
        BooksRepository.updateCounter(comment.getBookId());
    }