EJB3和手动层次结构持久性

我有一个遗留数据库,我使用EJB3进行建模。 数据库的状况非常糟糕,我们对数据库的插入方式有一些不寻常的限制。 现在我想在一个适合数据库结构的层次结构中建模数据库,但我希望能够单独手动插入每个实体,而不会让持久性管理器试图保持实体子项。

我正在尝试类似以下内容(样板左侧):

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

现在这引发了一个exception:

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

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

嘿欢迎来到JPA配置的拔毛。

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

  1. 手动持久保存新对象; 要么
  2. 自动保留它。

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

 @Entity @Table(name = "PARENT_TABLE") public class Parent { @Id private Long id; @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) private Collection children; public void addChild(Child child) { if (children == null) { children = new ArrayList(); } 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); 

现在我对此有点生疏,但我相信如果你这样做可能会遇到问题,因为在添加孩子之前父母是坚持的。 无论你做什么,都要小心并检查这个案例。