- экземпляры
- участники_экземпляра
- приглашения_экземпляра
Instance
Код: Выделить всё
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@OneToMany(mappedBy = "instance", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List members = new ArrayList();
@OneToMany(mappedBy = "instance", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List invitations = new ArrayList();
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime createdAt;
Код: Выделить всё
@ManyToOne
@JoinColumn(name = "instance_id", nullable = false)
private Instance instance;
@Id
@Column(name = "user_uuid")
@JdbcType(VarcharUUIDJdbcType.class)
private UUID uuid;
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime createdAt;
Код: Выделить всё
@ManyToOne
@JoinColumn(name = "instance_id", nullable = false)
private Instance instance;
@Id
@Column(name = "invited")
@JdbcType(VarcharUUIDJdbcType.class)
private UUID invited;
@Column(name = "invited_by")
@JdbcType(VarcharUUIDJdbcType.class)
private UUID invitedBy;
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime createdAt;
- При создании приглашения создается запись в «instance_invitation».
- Если оно принято, запись в «instance_invitations» удаляется. и еще один создается в «instance_members»
- Если предложение отклонено, запись в «instance_invitations» удаляется и отношения участников не создаются.
Если пользователь А решает удалить существующего пользователя с помощью функции «кинуть». (При этом удаляется только запись в «instance_members»), все работает нормально, поскольку хорошо.
Если пользователь A решает пригласить пользователя C после удаления пользователя B, программа аварийно завершает работу и переходит в спящий режим, выдает следующую ошибку:
Код: Выделить всё
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [me.test.game.model.InstanceMember#f9b56403-46a4-465b-a459-3de54e4abea8]Следующий код используется для persist (создать новую запись) объект в направлении сеанса:
Код: Выделить всё
protected void persistToSession(@Nonnull T data, @Nonnull DatabaseCallback callback) {
Session session = null;
T result = null;
try {
data.setCreatedAt(LocalDateTime.now());
data.setUpdatedAt(LocalDateTime.now());
session = getSessionFactory().openSession();
session.beginTransaction();
session.persist(data);
session.getTransaction().commit();
result = data;
}catch(Exception e) {
Main.log(this.getClass(), LogType.ERROR, "Error on PERSIST of model '" + tClass.getName() + "': " + e.getMessage());
// result = null;
} finally {
if (session != null) {
session.close();
}
}
T finalResult = (result);
callback.onQueryDone(finalResult);
}
Код: Выделить всё
public void update(T data, DatabaseCallback callback) {
Session session = null;
try {
data.setUpdatedAt(LocalDateTime.now());
session = getSessionFactory().openSession();
session.beginTransaction();
session.merge(data);
session.getTransaction().commit();
callback.onQueryDone(data);
}catch(Exception e) {
Main.log(this.getClass(), LogType.ERROR, "Error on UPDATE of model '" + tClass.getName() + " (Data: " + data + ")': " + e.getMessage());
callback.onQueryDone(null);
} finally {
if (session != null) {
session.close();
}
}
}
Код: Выделить всё
public void delete(T data, DatabaseCallback callback) {
try (Session session = getSessionFactory().openSession()) {
session.beginTransaction();
session.remove(data);
session.getTransaction().commit();
callback.onQueryDone(data);
} catch (Exception e) {
Main.log(this.getClass(), LogType.ERROR, "Error on DELETE of model '" + tClass.getName() + "': " + e.getMessage());
callback.onQueryDone(null);
}
}
Код: Выделить всё
public interface DatabaseCallback {
void onQueryDone(T result);
}
Ошибка сообщает, что не удалось найти строку с данным идентификатором, что верно, поскольку она была удалена в предыдущей транзакции, которая уже завершилась. После успешного обратного вызова удаления я удаляю запись в соответствующем списке («участники» или «приглашения» в модели «Экземпляр») вручную.
Мой вопрос следующий: : Откуда hibernate получает информацию о том, что объект не найден? Запрос на удаление был успешным, и поэтому запись больше не существует. Почему hibernate все еще знает об этом?
Я пробовал отладить SQL-запросы hibernate, но они возвращают только то, что я уже знаю: Hibernate предполагает, что участник все еще существует, хотя он был удален в предыдущей транзакции.
Обновление от 23 ноября:
- Я удалил операции «удаления» и просто удалил член из списка участников экземпляра, а затем обновить весь объект в базе данных: никаких изменений. Первая операция работает отлично, вторая выдает ту же ошибку.
Подробнее здесь: https://stackoverflow.com/questions/792 ... ier-exists
Мобильная версия