Hibernate - объект карты, принадлежащий двум другим объектам (объект с 2 родителями) - PullRequest
4 голосов
/ 22 августа 2010

У меня возникли проблемы с отображением следующего:

public class Operation {
  private Integer id;
  private String name;
  private List<Item> items = new ArrayList<Item>();
  //set/getters/hashcode/etc. omitted

  public void addItem(Item i,Operation end) {
     i.setOperationStart(this);
     i.setOperationEnd(end};
     items.add(i);
     end.getItems().add(i);
   }

public class Item {
  private Integer id;
  private String name;
  private Operation  operationStart;
  private Operation  operationEnd;
  //set/getters/hashcode/etc. omitted
}

Таким образом, в основном у Операции есть куча Предметов, а Предмет принадлежит 2 Операциям. Кроме того, не имеет смысла для элемента существовать, если одна из Операций не существует, то есть, если я удаляю одну из Операций, я хочу удалить элемент из того места, где он также хранится.

Есть ли у кого-нибудь указатель на то, как я сопоставлял бы вышеупомянутые классы, или могли бы привести некоторые примеры, показывающие, как сопоставить дочерний объект, у которого есть 2 родителя?

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

С объектно-ориентированной точки зрения то, что представлено, выглядит как две ManyToOne ассоциации между Item и Operation, одна из них является двунаправленной.Это может быть отображено так:

@Entity
public class Item {
  @Id private Integer id;
  private String name;
  @ManyToOne
  private Operation  operationStart;
  @ManyToOne
  private Operation  operationEnd;

  //set/getters/hashcode/etc. omitted
}

@Entity
public class Operation {
  @Id private Integer id;
  private String name;

  @OneToMany(cascade = CascadeType.REMOVE, mappedBy="operationStart")
  private List<Item> items = new ArrayList<Item>();

  //set/getters/hashcode/etc. omitted
}

Это должно привести к таблице [ITEM] с двумя FK, указывающими на [OPERATION].А заполнение коллекции items приведет к ограничению SELECT для одного из них (ID операции запуска в приведенном выше примере).

Я не знаю, имеет ли смысл этот сценарийно это IMO единственный сценарий, с которым может справиться Hibernate.Если это не то, что вам нужно, то я думаю, что у вас должно быть две коллекции на стороне Operation (которые вы, возможно, могли бы скрыть за дружественными методами).

Используете ли вы hbm.xml или аннотациине имеет значения.

1 голос
/ 23 августа 2010

Это звучит как сочетание отношения «многие ко многим» между Предметами и Операциями и троичного отношения между одним Предметом и двумя Операциями.

Предполагая, что ваша бизнес-логика зафиксирована ровно на двух Операциях наЭлемент, и не более того, я бы решил эту проблему следующим образом:

  • Если вы хотите чистую объектную модель, то создайте промежуточный объект для хранения ссылок на две операции, и ондолжен содержать один элемент в качестве компонента.
  • Отобразить элементы в hbm.По сути, каждая операция должна иметь список промежуточного объекта, а каждый промежуточный объект имеет один элемент.Когда вы удаляете промежуточный объект, каскадируйте удаление к элементу, но не к операциям.

Сложной частью, как вы сказали, является удаление операции.Независимо от того, используете ли вы промежуточный объект или нет, вам нужно каскадировать удаление в список с помощью all-delete-orphan.Тем не менее, я подозреваю, что у вас будут некоторые проблемы из-за кеша 2-го уровня.Единственный способ, который я знаю об этом, заключается в следующем:

  • перед удалением операции op1, обход графа объектов и отсоединение каждого промежуточного объекта от другой операции op2, и только после этого сброс.В противном случае hibernate откажется удалять промежуточные объекты, поскольку они все еще содержатся в некоторых наборах в других операциях.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...