我有一个遗留数据库,我正在使用 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 保留它!我希望能够首先坚持 parent ,然后是 child - 但不是在一起。有充分的理由想这样做,但它似乎并不想玩。
最佳答案
嘿,欢迎来到 JPA 配置这个令人毛骨悚然的地方。
在您的情况下,您有两种选择:
- 手动持久化新对象;或
- 自动持久化它。
要自动保留它,您需要注释关系。这是一个常见的一对多习惯用法:
@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);
现在我对此有点生疏,但我相信如果您这样做,您可能会遇到问题,因为在添加子项之前父项一直存在。无论你做什么,都要小心并检查这个案例。
关于java - EJB3 和手动层次结构持久性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/585454/