EJB3和手动层次结构持久性 [英] EJB3 and manual hierarchy persistence

查看:99
本文介绍了EJB3和手动层次结构持久性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a legacy database, which I am using EJB3 to model. The database is in quite a poor shape, and we have certain unusual restrictions on how we insert into the DB. Now I want to model the database in a hierarchy that fits in with the DB strucuture, but I want to be able to manually insert each entity individually without the persistence manager trying to persist the entities children.

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

I am trying something like the following (boilerplate left out):

@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保留它!我希望能够先坚持父母,然后坚持孩子 - 但不能在一起。想要这样做是有充分理由的,但似乎并不想玩。

Now I know the entity isn't marked PERSIST - I don't want the EntityManager to persist it! I want to be able to persist the parent first, and then the child - but not together. There are good reasons for wanting to do it this way, but it doesn't seem to want to play.

推荐答案

欢迎来到这是JPA配置的发型。

Heh welcome to the hair-pulling that is JPA configuration.

在你的情况下你有两个选择:

In your case you have two choices:


  1. 手动保留新对象;或

  2. 自动保留它。

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

To automatically persist it you need to annotate the relationship. This is a common one-to-many idiom:

@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);

由于级联持续存在,这将有效。

Because of the cascade persist this will work.

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

Note: You have to manage the relationship at a Java level yourself, hence manually setting the parent. This is important.

没有它,您需要手动保留对象。你需要一个EntityManager才能做到这一点,在这种情况下它很简单:

Without it you need to manually persist the object. You'll need an EntityManager to do that, in which case it is as simple as:

entityManager.persist(child);

此时它将正常工作(假设其他一切都有效)。

At which point it will work correctly (assuming everything else does).

对于纯粹的子实体,我赞成注释方法。它更容易。

For purely child entities I would favour the annotation approach. It's just easier.

我会用JPA提到一个问题:

There is one gotcha I'll mention with JPA:

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

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

Now I'm a little rusty on this but I believe that you may run into problems if you do this because the parent was persisted before the child was added. Be careful and check this case no matter what you do.

这篇关于EJB3和手动层次结构持久性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆