HibernateException:由 jpa 本身调用的共享引用(?)

HibernateException: Shared references invoked by jpa itself (?)

我目前在将对象写入数据库时​​遇到一些问题。我的问题确实出现在一个非常复杂的数据模型中,但我会尝试将其分解为一个易于理解的示例。

假设有 class A:

@Entity(name = "a")
@Table(schema = "foo")
public class A {
    private static final long serialVersionUID = -5305374150112492804L;
    logger = LoggerFactory.getLogger(A.class);

    @Id
    @Column(name = "tid", nullable = false, unique = true)
    @SequenceGenerator(name = "globalSequenceGen", schema = "foo", sequenceName = "foo_sequence")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "globalSequenceGen")
    private Integer TID;

    @Column(name = "b")
    private String bId;

    @OneToMany(targetEntity = B.class)
    @JoinColumn(name = "random_b_attribute", referencedColumnName = "b", updatable = false, insertable = false)
    private List<B> b;

    @PrePersist
    @PreUpdate
    public void prePersist() {
        bId = b == null || b.isEmpty() ? null : b.get(0).getRandomAttribute();
    }
    ...
}

引用的 class B 非常简单:它只包含 @Column 注释属性。请注意,A 的实例可以并且将在其属性 b 中引用 Bs 的相同 "Set" .

有第三个 class D 引用 A:

@Entity(name = "d")
@Table(schema = "foo")
public class D {
    private static final long serialVersionUID = -5305374150112492804L;
    logger = LoggerFactory.getLogger(D.class);

    @Id
    @Column(name = "tid", nullable = false, unique = true)
    @SequenceGenerator(name = "globalSequenceGen", schema = "foo", sequenceName = "foo_sequence")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "globalSequenceGen")
    private Integer TID;

    @Column(name = "a")
    private Integer aId;

    @ManyToOne(targetEntity = A.class)
    @JoinColumn(name = "a", referencedColumnName = "tid", updatable = false, insertable = false)
    private A a;

    @PrePersist
    @PreUpdate
    public void prePersist() {
        aId = a == null ? null : a.getTID();
    }
    ...
}

问题来了:

  1. 我确实从数据库中检索了 D 的对象(懒惰)。 None 其中确实引用了 A 的任何对象(例如,数据库中的列 a 是空的)。
  2. 我使用相同的 EntityManager 从数据库中检索 A 的所有对象,因为我稍后想将它们插入 D 实例(也是懒惰的)。
  3. 触摸任何D#aA#b属性。
  4. 尝试 EntityManager#persist 任何新创建的 D 实例最终会出现以下异常:
Caused by: org.hibernate.HibernateException: Found shared references to a collection: random.package.structure.A.b

在我的研究中,我发现错误可能是在提供相同的 Collection 时引起的(不要与具有相同条目的 Collection 混淆)。显然,这源于 jpa 本身对 A 实例的初始化?!似乎,回收相同的对象是个好主意 Collection,但在更新未更改的对象时显然会导致问题...

在持久化对象之前清除 EntityManager 似乎可以解决问题。但是,由于所有内容都是延迟读取的,之后使用这些对象会导致其他问题。

关于如何为 A 的每个实例创建新的 Collection 或以其他方式防止失败,您有任何提示吗?

非常感谢,如果我遗漏了任何信息,请尽管询问!

非常感谢您的回答! @crizzis 的提示起到了作用。

当然是@ManyToMany关系。我更改了我的数据模型(以使用映射表)并解决了我的问题!