Каскадное сохранение и существующий объект - PullRequest
1 голос
/ 21 апреля 2010

Я работаю с JPA и хочу сохранить объект (действие), состоящий из объекта (домен).

Существует код класса Action:

@Entity(name="action")
@Table(name="action")
public class Action {

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Column(name="num")
  private int num;

  @OneToOne(cascade= { CascadeType.PERSIST, CascadeType.MERGE,
      CascadeType.REFRESH })
  @JoinColumn(name="domain_num")
  private Domain domain;

  @Column(name="name")
  private String name;

  @Column(name="description")
  private String description;

  public Action() {
  }

  public Action(Domain domain, String name, String description) {
    super();
    this.domain=domain;
    this.name=name;
    this.description=description;
  }

  public int getNum() {
    return num;
  }

  public Domain getDomain() {
    return domain;
  }

  public String getName() {
    return name;
  }

  public String getDescription() {
    return description;
  }
}

Когда я сохраняю действие с новым Доменом, оно работает. Действие и Домен сохраняются. Но если я пытаюсь сохранить действие с существующим доменом, я получаю эту ошибку:

javax.persistence.EntityExistsException: 
Exception Description: Cannot persist detached object [isd.pacepersistence.common.Domain@1716286]. Class> isd.pacepersistence.common.Domain Primary Key> [8]

Как я могу сохранить свое действие и автоматически сохранить домен, если он не существует? Если он существует, как я могу просто сохранить действие и связать его с существующим доменом.

1 Ответ

1 голос
/ 21 апреля 2010

Из того исключения, которое вы опубликовали, похоже, что вы пытаетесь использовать отдельный Domain объект с новым Action объектом.Прежде чем сохранить действие, вам нужно заново присоединить объект Domain, используя метод EntityManger.merge:

domainObject = entityManager.merge(domainObject);
Action action = new Action(domainObject, "name", "description");
entityManager.persist(action);

Если вы хотите обработать оба случая, описанные в вашем вопросе, вы можете использовать слияние вместосохраняться на объекте Action.Метод слияния сохранит новое действие и повторно присоединит или сохранит объект Domain (поскольку вы указали Cascade.MERGE).

Action action = new Action(domainObject, "name", "description");
action = entityManager.merge(action);

Просто не забудьте использовать новый экземпляр объекта Domain, связанныйс действием после слияния.Если вы собираетесь использовать объект домена после объединения объекта Action, обязательно сделайте что-то вроде этого:

domainObject = action.getDomain();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...