程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何使用Spring Data JPA保存具有手动分配的标识符的实体?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何使用Spring Data JPA保存具有手动分配的标识符的实体??

开发过程中遇到如何使用Spring Data JPA保存具有手动分配的标识符的实体?的问题如何解决?下面主要结合日常开发的经验,给出你关于如何使用Spring Data JPA保存具有手动分配的标识符的实体?的解决方法建议,希望对你解决如何使用Spring Data JPA保存具有手动分配的标识符的实体?有所启发或帮助;

基本上,您正在从自动分配的标识符切换到手动定义的标识符,这对JPA和Spring Data级别都有很多影响。

数据库操作时间

在普通的JPA级别,持久性提供程序不必立即执行单个插入,因为它不必获取标识符值。这就是为什么它通常会延迟语句的执行,直到需要刷新为止(这是对的显式调用Entitymanager.flush(),即查询执行),因为这要求数据库中的数据是最新的以提供正确的结果或事务提交

Spring Data JPA存储库会在调用时自动使用默认事务save(…)。但是,如果您@transactional在依次注释的方法中调用存储库,则直到离开该方法,数据库交互才可能发生。

Entitymanager.persist(…) VS。 ….merge(…)

JPA要求Entitymanager客户代码区分保留一个全新实体或对现有实体进行更改。Spring Data存储库希望将客户端代码从不必处理这种区别中解放出来,因为业务代码不应因实现细节而过载。这意味着,Spring Data必须以某种方式将新实体与现有实体区分开。参文档中描述了各种策略。

如果是手动标识符,则默认情况下null将不检查标识符属性的值,因为null根据定义,该属性永远不会。一种标准模式是调整实体以实现Persistable并保持一个短暂的is- new-flag,并使用实体回调注释来翻转该标记。

@mappedSuperclass
public abstract class AbstractEntity<ID extends SALEspointIDentifIEr> implements Persistable<ID> {

  private @TransIEnt Boolean isNew = true;

  @OverrIDe
  public Boolean isNew() {
    return isNew;
  }


  @PrePersist
  @PostLoad
  voID markNotNew() {
    this.isNew = false;
  }

  // More code…
}

isNew声明为瞬态的,这样它就不会持久。该类型实现,Persistable便存储库save(…)方法的Spring Data JPA实现将使用该类型。上面的代码使用new标记设置为true,从用户代码创建实体,但是任何类型的数据库交互(保存或加载)都会将该实体转换为现有实体,因此save(…)将在Entitymanager.persist(…)最初触发但….merge(…)为所有后续操作触发。

我借此机会创建了DATAJPA-1600,并将此描述的摘要添加到了参文档中。

解决方法

我正在更新一个现有代码,该代码可将一个表中的副本或原始数据处理到同一数据库中的多个对象中。

以前,每种对象都有一个为每个表使用序列的生成的PK。

像这样:

@Id
@column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

为了重用导入表中的现有ID,我们为某些实体删除了GeneratedValue,例如:

@Id
@column(name = "id")
private Integer id;

对于这个实体,我没有更改我的JpaRepository,如下所示:

public interface EntityRepository extends JpaRepository<Entity,Integer> {
    <S extends Entity> S save(S entity);
}

现在,我正在努力理解具有默认传播和隔离级别的Spring事务(@transactional)中的以下行为:

  • 在实体上使用@GeneratedValue时,当我调用entityRepository.save(entity)时,我可以看到在激活了Hibernate show sql的情况下触发了插入请求(但是由于数据库未更改,似乎仅在缓存中)
  • 在实体上没有@GeneratedValue的情况下,仅激发选择请求(不尝试插入)

当我的实体(没有生成的值)以一种或多种关系映射到MyOtherEntity(有生成的值)时,这是一个大问题。

因此,我有以下错误:

ERROR: insert or update on table "t_other_entity" violates foreign key cons@R_262_9829@nt "other_entity_entity"
Détail : Key (entity_id)=(110) is not present in table "t_entity"

似乎合法,因为尚未为Entity发送插入内容,但是为什么呢?同样,如果我更改实体的ID并使用@GeneratedValue,则不会出现任何错误。

我正在使用Spring Boot 1.5.12,Java 8和POSTGReSQL 9

大佬总结

以上是大佬教程为你收集整理的如何使用Spring Data JPA保存具有手动分配的标识符的实体?全部内容,希望文章能够帮你解决如何使用Spring Data JPA保存具有手动分配的标识符的实体?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。