Потерял с JPA @OneToMany и композитный ПК - PullRequest
0 голосов
/ 14 августа 2010

Я довольно растерялся, отображая следующую структуру с аннотациями JPA.

+===========+             +====================+
| Offer     |             | Text               |
+-----------+ 1      0..* +--------------------+
| id (pk)   |-------------| textkey (pk)       |
| namekey   |             | languagecode (pk)  |
| ...       |             | text               |
+===========+             | ...                |
                          +====================+

Итак, у каждого предложения есть имя, которое известно i18n. Поскольку в приложении снова и снова возникают одни и те же случаи (предложение также имеет комментарий i18n, статья имеет имя i18n и т. Д.), Я хочу иметь текстовый объект с составным первичным ключом. Для каждого ключа столько записей, сколько поддерживаемых языков. Образцы текста:

+=====================================+
| textkey    | languagecode | text    |
+=====================================+
| offer5Name | en           | foo     |
| offer5Name | fr           | bar     |
| offer6Name | en           | hello   |
...

Сущность «Предложение» будет хранить текстовый текстовый ключ в своем столбце именных ключей.

Что касается Java, я бы хотел, чтобы в предложении был набор имен или, что еще лучше, карта имен, чтобы у меня был метод типа Text getName(String language) вместо Set<Text> getNames().

У меня уже есть текст и его составной первичный ключ TextPK:

@Entity
public class Text {

  @EmbeddedId
  private TextPK primaryKey;

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

PK

@Embeddable
public class TextPK implements Serializable {

  @Column(name = "textkey")
  private Long key;

  @Column(name = "languagecode")
  @Enumerated(EnumType.STRING)
  private LanguageCode languageCode;

Вопрос: как аннотировать переменную-член 'names' в классе Offer, чтобы получить то, что мне нужно?

1 Ответ

2 голосов
/ 09 сентября 2010

Хорошо, я снова отвечаю на свой вопрос ...

JPA 1.0 не поддерживает однонаправленные OneToMany (http://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.0_unidirectional_OneToMany_relationship_database), и это то, с чем я бы в итоге справился.

В моем случае лучше всего было создать промежуточную TextCollection сущность. Каждый объект домена (например, Offer) имеет отношение OneToOne к TextCollection для каждого из его текстовых атрибутов (имя, описание и т. Д.). Сам объект коллекции не имеет ничего, кроме идентификатора и двунаправленного отношения OneToMany к Text.

@Entity
@Table(name = "textcollection")
public class TextCollection {

  @Id
  @Column(name = "textkey")
  private String key;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "textCollection")
  private final Set<Text> texts = new HashSet<Text>();


@Entity
@Table(name = "text")
public class Text {

  @EmbeddedId
  private TextPK primaryKey;

  @Column(name = "text", nullable = false)
  private String text;

  @ManyToOne
  @JoinColumn(name = "textkey", insertable = false, updatable = false)
  private TextCollection textCollection;

@Entity
@Table(name = "offer")
public class Offer {

  @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  @JoinColumn(name = "namekey", nullable = false, insertable = true)
  private TextCollection name;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...