Вопрос

У меня есть два класса сущностей, аннотированных следующим образом

@Entity
class A {
   @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
   private List<B> b;
 ..
}

@Entity
class B {
   @ManyToMany(cascade=CascadeType.ALL)
   private List<A> a;
 ..
}

Если я храню экземпляр класса «B», отношения сохраняются в базе данных, и получатель в классе «A» возвращает правильное подмножество B. Однако, если я внесу изменения в список B в «A», изменения не сохранятся в базе данных?

Мой вопрос: как я могу сделать так, чтобы изменения в любом классе были "каскадными"? в другой класс?

РЕДАКТИРОВАТЬ: я пробовал разные варианты удаления параметра mappedBy и определения JoinTable (и столбцов), но я не смог найти правильную комбинацию.

Это было полезно?

Решение

Самый короткий ответ, кажется, вы не можете, и это имеет смысл. В двунаправленной ассоциации «многие ко многим» одна сторона должна быть главной и использоваться для сохранения изменений в базовой таблице соединений. Поскольку JPA не будет поддерживать обе стороны ассоциации, вы можете столкнуться с ситуацией с памятью, которую невозможно перезагрузить после сохранения в базе данных. Пример:

A a1 = new A();
A a2 = new A();
B b = new B();
a1.getB().add(b);
b.getA().add(a2);

Если бы это состояние можно было сохранить, вы бы получили следующие записи в таблице соединений:

a1_id, b_id
a2_id, b_id

Но как после загрузки JPA узнает, что вы намеревались сообщить b только о a2, а не a1? а как насчет а2, который не должен знать о б?

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

Другие советы

Вы указали обратные столбцы соединения?

@Entity
class A {
   @ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
   private List <B> b;
   ..
}

@Entity 
class B { 
   @ManyToMany 
   @JoinTable (
       name="A_B",
       joinColumns = {@JoinColumn(name="A_ID")},
       inverseJoinColumns = {@JoinColumn(name="B_ID")}
   )
   private List<A> a; 
   .. 
} 

Предполагается, что таблица соединения называется A_B со столбцами A_ID и B_ID.

  

Поскольку отношения являются двунаправленными, так как приложение обновляется   одна сторона отношений, другая сторона также должна обновляться,   и быть в синхронизации. В JPA, как и в Java в целом это   ответственность приложения или объектной модели для поддержания   отношения. Если ваше приложение добавляет одну сторону   отношения, то это должно добавить к другой стороне.

     

Это можно решить с помощью методов add или set в объектной модели   которые обрабатывают обе стороны отношений, поэтому код приложения   не нужно беспокоиться об этом. Есть два способа сделать это,   Вы можете добавить код обслуживания отношений только на одну сторону   отношений, и используйте только сеттер с одной стороны (например,   сделать другую сторону защищенной), или добавить его к обеим сторонам и обеспечить   Вы избегаете бесконечного цикла.

Источник: OneToMany # Getters_and_Setters

Вы пытались добавить параметр mappedBy в поле A в классе B следующим образом

@Entity
class B {
   @ManyToMany(cascade=CascadeType.ALL, mappedBy = "b")
   private List<A> a;
 ..
}

Возможно, в ответе A_M есть небольшая ошибка. По моему это должно быть:

   @Entity
   class B { 
   @ManyToMany 
   @JoinTable (
       name="A_B",
       joinColumns = {@JoinColumn(name="B_ID")},
       inverseJoinColumns = {@JoinColumn(name="A_ID")}
   )
   private List a; 
   .. 
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top