1

我有一个遗留数据库,我正在使用 EJB3 对其进行建模。数据库的状态很差,我们对如何插入数据库有一些不寻常的限制。现在我想在适合数据库结构的层次结构中对数据库进行建模,但我希望能够单独手动插入每个实体,而不需要持久性管理器尝试持久化实体子项。

我正在尝试类似以下的东西(样板被遗漏):

@Entity
@Table(name = "PARENT_TABLE")
public class Parent {
    @Id
    @Column(name = "ID")
    int id;

    @OneToMany
    List<Child> children;
}


@Entity
@Table(name = "CHILD_TABLE")
public class Child {
    @Id
    @Column(name = "ID")
    int id;   
}

现在这引发了一个异常:

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST

现在我知道实体没有被标记为 PERSIST - 我不希望 EntityManager 持久化它!我希望能够先坚持父母,然后是孩子——但不是在一起。想要这样做是有充分理由的,但它似乎不想玩。

4

1 回答 1

6

嘿,欢迎来到 JPA 配置这个令人毛骨悚然的地方。

在您的情况下,您有两种选择:

  1. 手动持久化新对象;或者
  2. 自动持久化它。

要自动保留它,您需要注释关系。这是一个常见的一对多习语:

@Entity
@Table(name = "PARENT_TABLE")
public class Parent {
  @Id private Long id;

  @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
  private Collection<Child> children;

  public void addChild(Child child) {
    if (children == null) {
      children = new ArrayList<Child>();
    }
    child.setParent(parent);
    children.add(child);
  }
}

@Entity
@Table(name = "CHILD_TABLE")
public class Child {
  @Id private Long id;

  @ManyToOne
  private Parent parent;

  public void setParent(Parnet parent) {
    this.parent = parent;
  }
}

Parent parent = // build or load parent
Child child = // build child
parent.addChild(child);

由于级联持续存在,这将起作用。

注意:您必须自己在 Java 级别管理关系,因此手动设置父级。这个很重要。

没有它,您需要手动持久化对象。您需要一个 EntityManager 来执行此操作,在这种情况下,它很简单:

entityManager.persist(child);

在这一点上它会正常工作(假设一切正常)。

对于纯子实体,我倾向于使用注释方法。这更容易。

我将在 JPA 中提到一个问题:

Parent parent = new Parent();
entityManager.persist(parent);
Child child = new Child();
parent.addChild(child);

现在我对此有点生疏,但我相信如果你这样做,你可能会遇到问题,因为在添加孩子之前父母已经坚持了下来。无论您做什么,都要小心并检查这种情况。

于 2009-02-25T10:35:24.217 回答