使用具有嵌入 ID 的实体删除数据库行

问题描述 投票:0回答:2

我正在开发一个使用 JPA、Rest、Hibernate、Spring Boot 并在后端运行 Java 的应用程序。

我从另一个方法调用此方法,如果有人删除与该参数关联的项目,则会清除记录。 我的日志让我知道参数 ID 正在传递到查询中,因此问题似乎源于查询本身。 当我测试我的代码是 Swagger 时,我只是不断收到“未找到数据”消息。

这是我第一次尝试删除具有嵌入 ID 的记录,但我似乎无法让查询正常工作。我做错了什么?

这是删除方法,我在其中进行查询:

 @Override
 @Transactional
  public void deleteParameterById(Long parameterId) {
 
    Query query = entityManager
     .createQuery("DELETE FROM ParameterEntity pa WHERE pa.ParameterEntityId.parameterId = ?1");
     query.setParameter(1, parameterId)
     .executeUpdate();

 }

这里是嵌入式ID(ParameterEntityId.java):

@Embeddable
public class ParameterEntityId implements Serializable {

  @Column(name = "PARAMETER_ID")
  private Long parameterId;

  @Column(name = "PARAMETER_ATTRIBUTE_TYPE_ID")
  private Long parameterAttributeTypeId;

这是我的实体文件(ParameterEntity.java):

@Entity
@Table(name = "parameter")
public class ParameterEntity {

  @EmbeddedId
  private ParameterEntityId parameterEntityId;

  @Column(name = "VALUE")
  private String value;

我发现很多使用 JPA 存储库的示例,但这不是这个应用程序的配置方式,我们使用的是实体。

我最初只是尝试编写一个本机查询并直接调用数据库表Parameters并直接选择parameter_cd,这样我就可以绕过这个嵌入式密钥,(数据库使用parameter_idparameter_attribute_type_id的复合键)但是当我在 Swagger 中测试它时,我只是收到一条“正在处理”消息,并且查询永远不会完成运行。

我还确保应用程序具有从表中编辑和删除的适当权限。

这是我原来的本机查询:

@Override
@Transactional
public void deleteParameterById(Long parameterId) {

      entityManager.createNativeQuery("DELETE FROM *dbname(redacted)*.parameter WHERE parameter_id = ?1")
      .setParameter(1, parameterId).executeUpdate();
  
  }
java database rest jpa
2个回答
1
投票

正如 Chris 在评论中已经写的那样,必须使用

parameterEntityId
属性的正确大小写来修复查询,以便您:

Query query =
    entityManager.createQuery(
        "DELETE FROM ParameterEntity pa WHERE pa.parameterEntityId.parameterId = ?1");

使用您的原始查询,会抛出此异常:

Caused by: org.hibernate.query.sqm.UnknownPathException: Could not resolve attribute 'ParameterEntityId' of 'it.so.entity.ParameterEntity' [DELETE FROM ParameterEntity pa WHERE pa.ParameterEntityId.parameterId = ?1]
    at org.hibernate.query.hql.internal.StandardHqlTranslator.translate(StandardHqlTranslator.java:88)
    at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.createHqlInterpretation(QueryInterpretationCacheStandardImpl.java:145)
    at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.resolveHqlInterpretation(QueryInterpretationCacheStandardImpl.java:132)
    at org.hibernate.internal.AbstractSharedSessionContract.interpretHql(AbstractSharedSessionContract.java:802)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:852)
    ... 49 more
Caused by: org.hibernate.query.sqm.PathElementException: Could not resolve attribute 'ParameterEntityId' of 'it.so.entity.ParameterEntity'

使用正确的查询,Hibernate 将 jpql 转换为以下 sql:

delete from parameter pe1_0 where pe1_0.parameter_id=?

与您的本机匹配,在单元测试执行中立即运行,没有错误。

正如您所说,此查询在 SQLDeveloper 中运行顺利,我怀疑当此查询在应用程序中运行时,可能会锁定在控制器和

deleteParameterById
之间的其余端点调用期间发生的数据库上的记录。方法。我建议检查是否有在此删除方法之前运行的东西可能会创建此锁。


0
投票

试试这个:

Query query = entityManager
 .createQuery("DELETE FROM ParameterEntity pa WHERE pa.ParameterEntityId.parameterId = :paramId");
 query.setParameter("paramId", parameterId).executeUpdate();
© www.soinside.com 2019 - 2024. All rights reserved.