首页 > 解决方案 > Hibernate 不使用 Id 来查找实体

问题描述

Hibernate 似乎没有为一个特定的类使用 Id 字段。我的设置如下所示:

@Data
@MappedSuperclass
public abstract class IdentifiableObject {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
}

@Data
@Entity
@Table(name = "A")
public class A extends IdentifiableObject {

    private String field;
    @ManyToOne(targetEntity = B.class)
    private B b;
}

@Data
@Entity
@Table(name = "B")
public class B extends IdentifiableObject {

    private TypeSomethingElse field;
    @ManyToOne(targetEntity = C.class)
    private C c;
    @OneToMany(
        cascade = CascadeType.ALL
    )
    private List<A> as;
}

@Data
@Entity
@Table(name = "C")
public class C extends IdentifiableObject {

    @OneToMany(
        cascade = CascadeType.ALL
    )
    private List<B> bs;
}

在我的代码中,我将对象 C 保存到数据库中,使用数据库中的数据执行一些计算,创建碧玉报告并再次从数据库中删除对象 C。删除 C 对象时出现此错误:

org.hibernate.HibernateException:找到了多个具有给定标识符的行:A(field="something")

在类中抛出此异常:

public abstract AbstractEntityLoader {
    protected Object load(
        SharedSessionContractImplementor session,
        Object id,
        Object optionalObject,
        Serializable optionalId,
        LockOptions lockOptions){
        // Some code
    }
}

当B对象触发加载方法时,传递给加载方法的id就是字段id的值。每当它为 A 对象触发时,它都会传递一个仅填充字段属性的 A 对象,我们的 id 为空。我个人认为该方法在这两种情况下都会使用 Id 字段,但事实并非如此。有谁知道这里发生了什么?

JPA 存储库:

我使用自动实现的接口进行删除。

public interface CRepository extends IdentifiableObjectRepository<C>, JpaRepository<C, Integer> {

    C findById(Integer cId);
}

PS: @Data 注解是 Lombok 的一部分,用于提供 getter 和 setter 以及其他一些有用的方法。

PPS:我已经能够通过向 JpaRepository 添加新的删除方法来使其工作:'void deleteById(Integer id)',因此默认 CRUDRepository 删除方法似乎存在问题。这感觉像是一种解决方法,我仍然想知道这个问题的原因是什么。

标签: javahibernate

解决方案


推荐阅读