JuH*_*m89 5 java hibernate spring-data spring-data-jpa
目前我开发了一个Spring Boot应用程序,它主要从消息队列(~5并发消费者)中提取产品评论数据并将它们存储到MySQL DB中.每个评论可以通过其reviewIdentifier(字符串)唯一标识,该标识符是主键并且可以属于一个或多个产品(例如,具有不同颜色的产品).以下是数据模型的摘录:
public class ProductPlacement implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "product_placement_id")
private long id;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="productPlacements")
private Set<CustomerReview> customerReviews;
}
public class CustomerReview implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "customer_review_id")
private String reviewIdentifier;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(
name = "tb_miner_review_to_product",
joinColumns = @JoinColumn(name = "customer_review_id"),
inverseJoinColumns = @JoinColumn(name = "product_placement_id")
)
private Set<ProductPlacement> productPlacements;
}
Run Code Online (Sandbox Code Playgroud)
队列中的一条消息包含1 - 15条评论和productPlacementId.现在我想要一种有效的方法来坚持产品的评论.每次进行审查时,基本上都需要考虑两种情况:
目前,我持久审查的方法并不是最佳的.它看起来如下(使用Spring Data JpaRespoitories):
@Override
@Transactional
public void saveAllReviews(List<CustomerReview> customerReviews, long productPlacementId) {
ProductPlacement placement = productPlacementRepository.findOne(productPlacementId);
for(CustomerReview review: customerReviews){
CustomerReview cr = customerReviewRepository.findOne(review.getReviewIdentifier());
if (cr!=null){
cr.getProductPlacements().add(placement);
customerReviewRepository.saveAndFlush(cr);
}
else{
Set<ProductPlacement> productPlacements = new HashSet<>();
productPlacements.add(placement);
review.setProductPlacements(productPlacements);
cr = review;
customerReviewRepository.saveAndFlush(cr);
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
更新问题1:我的Review-Repository上的简单@Lock是否会优先考虑唯一约束异常?
@Lock(LockModeType.PESSIMISTIC_WRITE)
CustomerReview findByReviewIdentifier(String reviewIdentifier);
Run Code Online (Sandbox Code Playgroud)
findByReviewIdentifier返回null时会发生什么?即使方法返回null,是否可以hibernate锁定reviewIdentifier以查找可能的插入?
谢谢!
从性能的角度来看,我将考虑通过以下更改来评估该解决方案。
我有一个同样的问题,即执行的 DML 语句中哪一个更有效。引用典型的 ManyToMany 映射与两个 OneToMany。
从配置角度来看,选项一可能更简单,但它产生的 DML 语句效率较低。
使用第二个选项,因为每当关联由 @ManyToOne 关联控制时,DML 语句始终是最有效的语句。
启用批处理支持将减少插入/更新相同数量记录时到数据库的往返次数。
hibernate.jdbc.batch_size = 50
hibernate.order_inserts = true
hibernate.order_updates = true
hibernate.jdbc.batch_versioned_data = true
当前代码获取ProductPlacement并为每个review它执行一个saveAndFlush,这会导致 DML 语句不进行批处理。
相反,我会考虑加载ProductPlacement实体并将其添加List<CustomerReview> customerReviews到实体Set<CustomerReview> customerReviews字段,最后在最后ProductPlacement调用该方法一次,并进行以下两个更改:merge
ProductPlacement实体成为关联的所有者,即通过将mappedBy属性移动到实体Set<ProductPlacement> productPlacements的字段上CustomerReview。CustomerReview实体实现equals和方法。我相信是唯一的并且是用户指定的。hashCodereviewIdentifierreviewIdentifier最后,当您通过这些更改进行性能调整时,请使用当前代码作为性能基准。然后进行更改并比较这些更改是否确实为您的解决方案带来了显着的性能改进。
| 归档时间: |
|
| 查看次数: |
8800 次 |
| 最近记录: |