JPA ManyToMany ссылка на вопрос - PullRequest
2 голосов
/ 19 апреля 2010

У меня есть три таблицы.AvailableOptions и PlanTypeRef с таблицей сопоставления ManyToMany с именем AvailableOptionPlanTypeAssoc.Урезанные схемы выглядят так:

CREATE TABLE [dbo].[AvailableOptions](
  [SourceApplication] [char](8) NOT NULL,
  [OptionId] [int] IDENTITY(1,1) NOT NULL,
  ...
)

CREATE TABLE [dbo].[AvailOptionPlanTypeAssoc](
  [SourceApplication] [char](8) NOT NULL,
  [OptionId] [int] NOT NULL,
  [PlanTypeCd] [char](2) NOT NULL,
)

CREATE TABLE [dbo].[PlanTypeRef](
  [PlanTypeCd] [char](2) NOT NULL,
  [PlanTypeDesc] [varchar](32) NOT NULL,
)

И код Java выглядит следующим образом.

//AvailableOption.java
@ManyToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinTable(
  name = "AvailOptionPlanTypeAssoc",
  joinColumns = { @JoinColumn(name = "OptionId"),
                  @JoinColumn(name="SourceApplication")},
  inverseJoinColumns=@JoinColumn(name="PlanTypeCd"))
List<PlanType> planTypes = new ArrayList<PlanType>();

//PlanType.java
@ManyToMany
@JoinTable(
  name = "AvailOptionPlanTypeAssoc",
  joinColumns = { @JoinColumn(name = "PlanTypeCd")},
  inverseJoinColumns={@JoinColumn(name="OptionId"),
                      @JoinColumn(name="SourceApplication")})
List<AvailableOption> options = new ArrayList<AvailableOption>();

Проблема возникает при выборе выбора для AvailableOptions, который он присоединяет к себе.Обратите внимание на следующий код SQL от backtrace.Второе внутреннее соединение должно быть в PlanTypeRef.

SELECT t0.OptionId, 
  t0.SourceApplication, 
  t2.PlanTypeCd, 
  t2.EffectiveDate, 
  t2.PlanTypeDesc, 
  t2.SysLstTrxDtm, 
  t2.SysLstUpdtUserId, 
  t2.TermDate 
FROM dbo.AvailableOptions t0 
  INNER JOIN dbo.AvailOptionPlanTypeAssoc t1 
    ON t0.OptionId = t1.OptionId AND t0.SourceApplication = t1.SourceApplication 
  INNER JOIN dbo.AvailableOptions t2 
    ON t1.PlanTypeCd = t2.PlanTypeCd 
WHERE (t0.SourceApplication = ? AND t0.OptionType = ?) 
ORDER BY t0.OptionId ASC, t0.SourceApplication ASC 
[params=(String) testApp, (String) junit0]}

1 Ответ

3 голосов
/ 20 апреля 2010

Вы отображаете двунаправленную ассоциацию. Это означает, что вы должны выбрать одну сторону в качестве владельца ассоциации. Эта сторона будет отвечать за обновление отношений в базе данных.

Если вы выбрали AvailableOption в качестве владельца отношения и вам нужен новый PlanType для него, вы должны добавить тип завода к опции. Добавление опции только к типу установки не будет иметь никакого эффекта.

Вот отображение:

//AvailableOption.java
@ManyToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinTable(
  name = "AvailOptionPlanTypeAssoc",
  joinColumns = { @JoinColumn(name = "OptionId"),
                  @JoinColumn(name="SourceApplication")},
  inverseJoinColumns=@JoinColumn(name="PlanTypeCd"))
List<PlanType> planTypes = new ArrayList<PlanType>();

//PlanType.java
@ManyToMany(
    mappedBy = "planTypes"
)
List<AvailableOption> options = new ArrayList<AvailableOption>();

Вы также можете обратиться к главе * 2.28

документации по аннотации в спящем режиме.

С уважением David

...