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

时间:2019-04-05 17:01:29

标签: java hibernate jpa entitymanager

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

假设有一个课程 A

    searchHandler(event) {
    let keyword = event.target.value;
    clearTimeout(this.typingTimer);
    this.typingTimer=setTimeout(()=>{
      let filter= {

        "where": {
          "or": [
            {
              "companyName":{"regexp":keyword +"/i"}
            },
            {
              "primaryPhone":{"regexp":keyword +"/i"}
            },
            {
              "emailAddress":{"regexp":keyword +"/i"}
            },
            {
              "venueCode":{"regexp":keyword +"/i"}
            },
            {
              "website":{"regexp":keyword +"/i"}
            },
          ]
        }
      }

      this.props.getParties(filter);
      let filtered = this.state.data.filter(item => {
        return (
          item.companyName.toLowerCase().indexOf(keyword) > -1 ||
          item.primaryPhone.toLowerCase().indexOf(keyword) > -1 ||
          item.emailAddress.toLowerCase().indexOf(keyword) > -1 ||
          item.venueCode.toLowerCase().indexOf(keyword) > -1 ||
          item.website.toLowerCase().indexOf(keyword) > -1 ||
          item.description.toLowerCase().indexOf(keyword) > -1
        );
      });

      if (keyword === "") {
        filtered = [];
        this.getData();
      }

      this.setState({
        filtered,
      });
      const { skip } = this.state;
      if(this.state.filtered.length>0 || !this.state.filtered.length){
        this.setState({
          filtered:[],
          skip: skip - skipDecrement
        })
      }
    },550)

  }

所引用的类 B 非常简单:它仅包含@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(); } ... } 带注释的属性。请注意, A 实例可以并且将在其属性@Column中引用 B 的相同“集合”。

引用 A 的是第三类 D

b

出现问题:

  1. 我确实从数据库中检索了 D 的对象(惰性)。它们都没有引用 A 的任何对象(例如,数据库中的 a 列为空)。
  2. 我确实使用相同的@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(); } ... } 从数据库中检索了 A 的所有对象,稍后我希望将它们插入 D 实例中(也是惰性的)。
  3. 触摸任何EntityManagerD#a属性。
  4. 尝试A#b任何新创建的 D 实例最终会导致以下异常:
EntityManager#persist

在研究过程中,我发现提供相同的Caused by: org.hibernate.HibernateException: Found shared references to a collection: random.package.structure.A.b 时可能会引起错误(不要与具有相同条目的Collection混淆)。显然,这是由jpa本身对 A 实例的初始化造成的吗?回收一个相同的Collection似乎是一个好主意,但显然在更新未更改的对象时会引起问题...

在持久保存对象之前清除Collection似乎可以解决问题。但是,由于以后使用这些对象将所有内容懒惰地读取,将导致其他问题。

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

在此先感谢您,如果我确实错过了任何信息,请问一下!

1 个答案:

答案 0 :(得分:0)

非常感谢您的回答! @crizzis的提示可以解决问题。

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