当前位置: 首页 > 知识库问答 >
问题:

为使用IdClass声明的复合键deleteById的JPA查询

梁鸣
2023-03-14

如果使用@idclass声明了我的(复合)主键,那么如何编写@query以便能够使用集合 发出delete查询?

尽管使用@query,但级联实际上会触发删除关联的另一个实体吗?

@Entity
@Table(name = "myentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@IdClass(MyIdClass.class)
public class MyEntity {

    @Id
    @Column(updatable = false)
    private String foo;

    @Id
    @Column(updatable = false)
    private String bar;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "my_foreign_key", referencedColumnName = "external_pk")
    private AnotherEntity anotherEntity;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MyIdClass implements Serializable {

    private String foo;
    private String bar;
}
@Entity
@Table(name = "anotherentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class AnotherEntity {

    @Id
    @Column(name = "external_pk", nullable = false, updatable = false)
    private String externalPk;
}

以下资源:

  1. https://www.baeldung.com/spring-data-jpa-query
  2. https://www.baeldung.com/spring-data-jpa-delete
  3. https://stackoverflow.com/a/36765129/9768291

我也发现了这个问题,这个问题似乎非常接近我要找的,但不幸的是没有答案。

@Repository
public interface MyCRUDRepository extends CrudRepository<MyEntity, MyIdClass> {

    @Modifying
    @Query("DELETE FROM myentity m WHERE m IN ?1") // how do I write this?
    void deleteAllWithIds(Collection<MyIdClass> ids);
}

然而,我不完全确定批处理的内部要求是什么。例如,如果我在for-loop执行deletebyid,那么交替的selectdelete语句会阻止批处理发生吗?关于这一点的文档很少。

共有1个答案

巫马欣嘉
2023-03-14
@Embedded
@AttributeOverrides({
  @AttributeOverride(name = "foo",
    column = @Column(name = "foo", insertable = false, updatable = false)),
  @AttributeOverride(name = "bar",
    column = @Column(name = "bar", insertable = false, updatable = false))})
private MyIdClass id;
@Modifying
@Query("DELETE FROM MyEntity me WHERE me.id in (:ids)")
void deleteByIdIn(@Param("ids") Collection<MyIdClass> ids);

这将生成一个查询:delete from myentity where bar=?还有foo=?[或bar=?和foo=?]...,导致此测试通过(下表记录插入到myentity(foo,bar)值('foo1','bar1')、('foo2','bar2')、('foo3','bar3')、('foo4','bar4');):

@Test
@Transactional
void deleteByInWithQuery_multipleIds_allDeleted() {
  assertEquals(4, ((Collection<MyEntity>) myEntityRepository.findAll()).size());

  MyIdClass id1 = new MyIdClass("foo1", "bar1");
  MyIdClass id2 = new MyIdClass("foo2", "bar2");

  assertDoesNotThrow(() -> myEntityRepository.deleteByIdIn(List.of(id1, id2)));
  assertEquals(2, ((Collection<MyEntity>) myEntityRepository.findAll()).size());
}
 类似资料:
  • 我正在尝试使用hibernate解决应用程序中的数据库映射问题。我们使用JPA注释这些类,到目前为止我们是成功的。但是,我们现在想引入一个组合键,它包含一个标识客户的唯一字符串和一个标识数据库条目的字符串。为了设置复合键,我们使用一个名为MandtId.java的IdClass。 然而,我们的映射似乎不起作用,因为它在另一侧找不到要连接的列。 以下是一些代码片段来显示我们的注释: MandtId.

  • 问题内容: 我有以下表格如何将它们映射到JPA实体: 事件表与会议表具有一对多关系。如何在JPA中映射这种双向关系? 问题答案: 在JPA 2.1规范的第2.4.1节中讨论。

  • EmbeddedId或IdClass注释用于表示复合主键。如何在没有(EmbeddedId或IdClass)的情况下使用复合主键? 如果可以在没有(EmbeddedId或IdClass)的情况下使用复合主键,那么如何使用EntityManager.find(Entity Class,Object primaryKey)方法在复合主键(Multiple primaryKey)的情况下查找实体(因为没

  • 我有以下实体: 我第一次使用复合主键,所以我不知道它应该如何工作。问题可能来自定义。第二个参数应该表示ID。但是没有一个主键,而是有两个主键,所以我认为我应该将id类添加到id参数中,但这不起作用。如何使用带有CrudRepository的IdClass键保存具有复合主实体?

  • 问题内容: 我的JPA模型中有以下类(省略了getters,setters和无关字段): 我需要定义一个类,使得当从所述类生成DDL时,相应的表的主键被由密钥和。我尝试了以下方法: 但这会为表生成以下内容: 请注意,和都是可为空的,当我尝试将DDL加载到SQL Server时会导致以下错误 无法在表“ PRICE”中的可为空的列上定义PRIMARY KEY约束 我不明白为什么这些可以为空,因为在域

  • 我有一个遗留数据库(实际上是Cobol文件),我正在使用Hibernate/JPA的专有JDBC驱动程序访问它。 实体有一个包含2列的复合主键:和。 在遗留数据中有相同的记录,这些记录可以具有的特定值,也可以在表示'All Sites'的列中具有NULL的记录。该文件的理论是,如果您找不到特定的SITE的,那么您可以在中使用NULL查找记录(the'catk-all')。 我不能改变这个“表”的结