Как определить многие ко многим себе в JPA? - PullRequest
1 голос
/ 17 ноября 2010

Я пытаюсь определить эту схему SQL в JPA:

TABLE event (id INT)
TABLE chain (predecessor INT, successor INT)

Другими словами, каждое событие имеет ряд преемников, которые сами являются событиями. Я пытаюсь сделать это в JPA:

@Entity
public class Event {
  @Id Integer id;
  @ManyToMany(cascade = CascadeType.PERSIST)
  @JoinTable(
    name = "chain",
    joinColumns = @JoinColumn(name = "successor"),
    inverseJoinColumns = @JoinColumn(name = "predecessor")
  )
  private Collection<Event> predecessors;
}

@Entity
public class Chain {
  @Id Integer id;
  @ManyToOne(cascade = CascadeType.PERSIST)
  @JoinColumn(name = "predecessor")
  private Event predecessor;
  @ManyToOne(cascade = CascadeType.PERSIST)
  @JoinColumn(name = "successor")
  private Event successor;
}

Это правильно?

Ответы [ 2 ]

1 голос
/ 17 ноября 2010

Если вы используете @ManyToMany, вам не нужна сущность Chain (в противном случае, если вам нужна сущность Chain, например, для хранения дополнительных данных, связанных с реляцией, вам нужно объявить две однозначные-множество отношений между Event и Chain).

1 голос
/ 17 ноября 2010

Обычно нельзя одновременно определить ManyToMany с JoinTable, а затем отдельно определить таблицу соединения как ее собственный объект. Соединительные таблицы обычно не являются сущностями, они просто объединяют таблицы, и поставщик управляет ими изнутри. Вы создаете много головной боли для себя, чтобы правильно поддерживать состояние памяти приложения при изменении одного или другого. (Что необходимо, если, например, вы хотите использовать кэширование L2.)

Таким образом, любой из них работает нормально, вместе взятые, они являются своего рода соусом. Обычно, если вы определили Цепь как сущность, у вас просто будет список Цепочек на Событии. Также не переопределять его как JoinTable на событие. Имеет ли это смысл?

(и, как это в настоящее время строго определено, он сломается, если вы попытаетесь внести изменения в коллекцию по событию, если только этот идентификатор не является последовательностью, созданной базой данных.)

Изменить: что-то вроде этого -

@Entity
public class Event {
  @Id Integer id;

  @OneToMany(cascade = CascadeType.PERSIST, mappedBy="successor")
  private Collection<Chain> predecessorChains;
}

То, что вы написали изначально, можно заставить работать, если вы поймете, что Collection<Event> predecessors по своей сути только для чтения и станет fubared, если вы попытаетесь кешировать его в L2. Тот факт, что вы положили CascadeType, делает одну вещь, которую вы хотели бы иметь возможность добавлять и удалять События в / из этого, которая взорвется, когда hibernate попытается выполнить недопустимый SQL.

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