Как реализовать поведение удаления после удаления в JoinTable с помощью EclipseLink jpa?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как реализовать поведение удаления после удаления в JoinTable с помощью EclipseLink jpa?

Сообщение Anonymous »

Наличие однонаправленного сопоставления ManyToMany в объекте с именем A к объекту с именем B в поле с именем files:

Код: Выделить всё

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = JOIN_TABLE_NAME)
private List files = new ArrayList();
, который создает таблицу соединения с идентификаторами каждого объекта в качестве составного первичного ключа.
Автоматически, когда элемент удаляется из списка файлов и объект сохраняется, строка также удаляется из таблицы соединения.
Я хотел бы реализовать такое поведение:
Каждый раз, когда строка удаляется из этой таблицы соединения, проверяйте, нет ли больше строк с B-id в качестве удаленного B-id строки, если поэтому удалите строки из таблицы B, соответствующие этому B-id.
Это можно реализовать несколькими способами. Некоторые из них я пробовал, но они неудовлетворительны или не работают:
Создайте таблицу соединений как отдельный объект и добавьте метод удаления сообщения. Однако этот метод не вызывается:

Код: Выделить всё

@Entity
@PrimaryKeyJoinColumns(
@PrimaryKeyJoinColumn(name = "a_id"),
@PrimaryKeyJoinColumn(name = "b_id")
)
@Table(name = JOIN_TABLE_NAME)
public class ABjoinTable {

@EmbeddedId
private ABId abid;

@Embeddable
public static final class ABId {

@Column(name = "a_id);
public long aid;

@Column(name = "b_id);
public long bid;
}

@PostRemove
public void removeDanglingFiles() {
// not called
}
}
Создайте триггер удаления для объединяемой таблицы, однако объект B имеет

Код: Выделить всё

PostRemove
метод уже реализован, который в этом решении
не будет вызываться (триггер находится на уровне базы данных).
Используйте метод PostUpdate для объекта A и удалите висячие строки вручную, однако строки еще не удаляются из таблицы соединения в контексте обновления после обновления:

Код: Выделить всё

@PostLoad
public void createFilesSnapshot() {
filesSnapshot = new ArrayList(this.files);
}

@PostUpdate
public void removeDanglingFiles() {
// if there are no more references to other Bids, delete that B
val removed = filesSnapshot.stream()
.filter(b -> !this.files.contains(b))
.map(PersistentObject::getId)
.collect(Collectors.toSet());
try (val em = JPAutil.getEntityManager()) {
val tx = em.getTransaction();
tx.begin();
for (val rId : removed) {
val q = em.createQuery("SELECT a" +
" FROM A a JOIN a.files b" +
" WHERE b.id = :bId", B.class);
q.setParameter("bId", rId);
val result = q.getResultList();
if (result.size() == 0) { // at this point in post load, join table row is not yet removed, so size is >= 1
em.remove(...);
}
}
tx.commit();
} catch (final Exception e) {
}
}
Использование поставщика jpa EclipseLink и базы данных MySql.

Подробнее здесь: https://stackoverflow.com/questions/798 ... selink-jpa
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»