【问题标题】:How to perform an upsert on entity with JoinColumn in JPA and Hibernate如何在 JPA 和 Hibernate 中使用 JoinColumn 对实体执行 upsert
【发布时间】:2022-01-16 03:59:48
【问题描述】:

hibernate-core 与 JPA 集成相当新。我们的实体看起来像

@MappedSuperclass
abstract class BasicEntity {

    @Id
    @GenericGenerator(name="uuid",strategy="uuid")
    @GeneratedValue(generator="uuid")
    private String id;

}

@Entity
@Table(name = "book")
class Book extends BasicEntity { 
    @ManyToOne
    @JoinColumn(name="book_genre")
    Genre genre

    @Column(name="texture")
    String texture;
}

@Data //lombok
@Entity
@Table(name="user_book_mapping")
class UserBookMapping extends BasicEntity {
    @ManyToOne
    @JoinColumn(name = "book_id")
    private Book book;
    
    @Column(name="user_id")
    String user_id;
}

我要对用户阅读的每一本书执行upsert(同一用户可以阅读一本书两次)UserBookMapping 表。请求对象包含一组用户和书籍[{userId, bookId}] 属性供我处理。

目前我遇到了一个解决方案,我最终首先从主表中获取 Book 实体,然后使用 userId+bookId 的组合获取这样的行是否已经存在,然后创建 @ 的新实例987654327@将其写入数据库。

在我看来,这在任何意义上都没有优化。理论上(以及在 NoSql 世界中),我要做的就是确保请求有效的bookIdsEXISTS),然后为UserBookMapping 执行UPSERT。但我对在计算时将数据写入和将数据表述为 java 对象的方式感到困惑。

第一季度。我真的需要构造Book 实体吗?

第二季度。什么是干净的方式来做我想要实现的目标?

【问题讨论】:

  • 您能说明一下想要的效果吗?您希望插入哪个数据实体,Book
  • 如果您只处理现有的Books 并且只想在BookUserBookMapping 之间建立关联,您可以简单地使用entityManager.getReference()。无需实际获取Book 实体
  • @crizzis 感谢您的回复。我正在尝试更新UserBookMapping,您能否详细说明entityManager.getReference 方面?

标签: java sql hibernate jpa


【解决方案1】:

正如@crizzis 所建议的,您可以这样做:

Book book = entityManager.getReference(Book.class, bookId);
Long booksPerUserCount = entityManager.createQuery(
    "select count(bu) from UserBookMapping bu where bu.book = :book and bu.user_id = :userId",
 Long.class )
.setParameter("book", book)
.setParameter("userId", userId)
.getSingleResult(); 

if (booksPerUserCount == 0) {
   UserBookMapping userBook = new UserBookMapping();
   userBook.setBook(book);
   userBook.setUserId(userId);
   entityManager.persist(userBook);
}

但只有当您确定存在 ID 为 bookId 的书时,它才会起作用。 您可以在hibernate documentation 中阅读有关entityManager.getReference() 的信息。

还请注意,在 hibernate/jpa 实体中使用 @Data lombok 注释时应谨慎,例如参见 this article

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-25
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 2013-04-26
    • 1970-01-01
    相关资源
    最近更新 更多