Исключение спящего режима при сохранении данных арены (строка с данным идентификатором не существует)JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Исключение спящего режима при сохранении данных арены (строка с данным идентификатором не существует)

Сообщение Anonymous »

Я впервые интегрирую Hibernate ORM в свой проект, и у меня возникли проблемы с отладкой исключения org.hibernate.UnresolvableObjectException: строк с данным идентификатором не существует исключение, и я не совсем уверен, связано ли это с тем, что я неправильно аннотировал свой класс, или я делаю что-то совершенно неправильно.

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

[09:19:38 INFO]: [STDOUT] [org.hibernate.engine.jdbc.spi.SqlStatementLogger] Hibernate: select am1_0.id,a1_0.arena_manager_id,a1_0.name,a1_0.id,a1_0.car_part_locations,a1_0.corners,a1_0.schematic,a1_0.spawn,a1_0.truck from arena_manager am1_0 left join arena a1_0 on am1_0.id=a1_0.arena_manager_id where am1_0.id=?
[09:19:38 ERROR]: [Murder Run] Exception while handling click event in inventory 'Create or modify a lobby', slot=16, item=GREEN_WOOL
org.hibernate.UnresolvableObjectException: No row with the given identifier exists:  [io.github.pulsebeat02.murderrun.game.arena.ArenaManager#5]
at org.hibernate.UnresolvableObjectException.throwIfNull(UnresolvableObjectException.java:49) ~[?:?]
at org.hibernate.event.internal.DefaultRefreshEventListener.refresh(DefaultRefreshEventListener.java:201) ~[?:?]
at org.hibernate.event.internal.DefaultRefreshEventListener.refresh(DefaultRefreshEventListener.java:184) ~[?:?]
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:109) ~[?:?]
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:55) ~[?:?]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[?:?]
at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1218) ~[?:?]
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1181) ~[?:?]
at MurderRun-1.21.1-v1.0.0-all-1729700029542.jar/io.github.pulsebeat02.murderrun.data.hibernate.controllers.AbstractController.serialize(AbstractController.java:51) ~[MurderRun-1.21.1-v1.0.0-all-1729700029542.jar:?]
at MurderRun-1.21.1-v1.0.0-all-1729700029542.jar/io.github.pulsebeat02.murderrun.MurderRun.updatePluginData(MurderRun.java:158) ~[MurderRun-1.21.1-v1.0.0-all-1729700029542.jar:?]
at MurderRun-1.21.1-v1.0.0-all-1729700029542.jar/io.github.pulsebeat02.murderrun.gui.lobby.LobbyModificationGui.createNewLobby(LobbyModificationGui.java:191) ~[MurderRun-1.21.1-v1.0.0-all-1729700029542.jar:?]
at com.github.stefvanschie.inventoryframework.gui.GuiItem.callAction(GuiItem.java:178) ~[?:?]
at com.github.stefvanschie.inventoryframework.pane.PatternPane.click(PatternPane.java:216) ~[?:?]
at com.github.stefvanschie.inventoryframework.gui.InventoryComponent.click(InventoryComponent.java:205) ~[?:?]
at com.github.stefvanschie.inventoryframework.gui.type.ChestGui.click(ChestGui.java:161) ~[?:?]
at com.github.stefvanschie.inventoryframework.gui.GuiListener.onInventoryClick(GuiListener.java:84) ~[?:?]
at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor85.execute(Unknown Source) ~[?:?]
at org.bukkit.plugin.EventExecutor$2.execute(EventExecutor.java:77) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:1.21.1-128-d348cb8]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at net.minecraft.server.network.ServerGamePacketListenerImpl.handleContainerClick(ServerGamePacketListenerImpl.java:3224) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.network.protocol.game.ServerboundContainerClickPacket.handle(ServerboundContainerClickPacket.java:69) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.network.protocol.game.ServerboundContainerClickPacket.handle(ServerboundContainerClickPacket.java:33) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.network.protocol.PacketUtils.lambda$ensureRunningOnSameThread$0(PacketUtils.java:56) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.TickTask.run(TickTask.java:18) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.util.thread.BlockableEventLoop.doRunTask(BlockableEventLoop.java:151) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.util.thread.ReentrantBlockableEventLoop.doRunTask(ReentrantBlockableEventLoop.java:24) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:1535) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:201) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.util.thread.BlockableEventLoop.pollTask(BlockableEventLoop.java:125) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:1512) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:1505) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.util.thread.BlockableEventLoop.managedBlock(BlockableEventLoop.java:135)  ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.managedBlock(MinecraftServer.java:1464) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:1471) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1316) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:329) ~[paper-1.21.1.jar:1.21.1-128-d348cb8]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
Для контекста, вот мой ArenaManager.java

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

package io.github.pulsebeat02.murderrun.game.arena;

import io.github.pulsebeat02.murderrun.data.hibernate.HibernateIdentifiers;
import jakarta.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.bukkit.Location;
import org.checkerframework.checker.nullness.qual.KeyFor;
import org.checkerframework.checker.nullness.qual.Nullable;

@Entity
@Table(name = "arena_manager")
public final class ArenaManager implements Serializable {

@Serial
private static final long serialVersionUID = -2378194945450834205L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id = HibernateIdentifiers.ARENA_MANAGER_ID;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@MapKeyColumn(name = "name")
@JoinColumn(name = "arena_manager_id")
@Column(name = "arena")
private final Map arenas;

public ArenaManager() {
this.arenas = new HashMap();
}

public void addArena(
final String name,
final Location[] corners,
final Location[] itemLocations,
final Location spawn,
final Location truck
) {
final ArenaSchematic schematic = ArenaSchematic.copyAndCreateSchematic(name, corners);
final Arena arena = new Arena(schematic, name, corners, itemLocations, spawn, truck);
this.arenas.put(name, arena);
}

public @Nullable Arena getArena(final String name) {
return this.arenas.get(name);
}

public void removeArena(final String name) {
this.arenas.remove(name);
}

public Map getArenas() {
return this.arenas;
}

public Set  getArenaNames() {
return this.arenas.keySet();
}
}
Арена.java

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

package io.github.pulsebeat02.murderrun.game.arena;

import io.github.pulsebeat02.murderrun.data.hibernate.HibernateIdentifiers;
import io.github.pulsebeat02.murderrun.data.hibernate.converters.LocationConverter;
import io.github.pulsebeat02.murderrun.utils.RandomUtils;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.io.Serial;
import java.io.Serializable;
import org.bukkit.Location;
import org.bukkit.util.BoundingBox;

@Entity
@Table(name = "arena")
public final class Arena implements Serializable {

@Serial
private static final long serialVersionUID = -6251041532325023867L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id = HibernateIdentifiers.ARENA_ID;

@Column(name = "schematic")
private final ArenaSchematic schematic;

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

@Convert(converter = LocationConverter.class)
@Column(name = "corners")
private final Location[] corners;

@Convert(converter = LocationConverter.class)
@Column(name = "car_part_locations")
private final Location[] carPartLocations;

@Convert(converter = LocationConverter.class)
@Column(name = "spawn")
private final Location spawn;

@Convert(converter = LocationConverter.class)
@Column(name = "truck")
private final Location truck;

public Arena(
final ArenaSchematic schematic,
final String name,
final Location[] corners,
final Location[] carPartLocations,
final Location spawn,
final Location truck
) {
this.schematic = schematic;
this.name = name;
this.corners = corners;
this.carPartLocations = carPartLocations;
this.spawn = spawn;
this.truck = truck;
}

public String getName() {
return this.name;
}

public Location getFirstCorner() {
return this.corners[0];
}

public Location getSecondCorner() {
return this.corners[1];
}

public Location getSpawn() {
return this.spawn;
}

public Location getTruck() {
return this.truck;
}

public Location[] getCorners() {
return this.corners;
}

public ArenaSchematic getSchematic() {
return this.schematic;
}

public BoundingBox createBox() {
return BoundingBox.of(this.corners[0], this.corners[1]);
}

public Location[] getCarPartLocations() {
return this.carPartLocations;
}

public Location getRandomItemLocation() {
final int length = this.carPartLocations.length;
if (length == 0) {
return this.spawn;
}

final int index = RandomUtils.generateInt(length);
final Location location = this.carPartLocations[index];
final Location drop = location.clone();
drop.add(0, 1.5,  0);

return drop;
}
}
ArenaSchematic.java

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

package io.github.pulsebeat02.murderrun.game.arena;

import static java.util.Objects.requireNonNull;

import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import io.github.pulsebeat02.murderrun.data.hibernate.converters.BlockVectorConverter;
import io.github.pulsebeat02.murderrun.data.hibernate.converters.PathConverter;
import io.github.pulsebeat02.murderrun.utils.IOUtils;
import it.unimi.dsi.fastutil.io.FastBufferedOutputStream;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serial;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import org.bukkit.Location;
import org.bukkit.World;

public final class ArenaSchematic implements Serializable {

@Serial
private static final long serialVersionUID = 4953428050756665476L;

@Convert(converter = PathConverter.class)
@Column(name = "schematic_path")
private final Path schematicPath;

@Convert(converter = BlockVectorConverter.class)
@Column(name = "origin")
private final BlockVector3 origin;

public ArenaSchematic(final Path schematicPath, final BlockVector3 origin) {
this.schematicPath = schematicPath;
this.origin = origin;
}

public static ArenaSchematic copyAndCreateSchematic(final String name, final Location[] corners) {
try {
final Clipboard clipboard = performForwardExtentCopy(corners);
final Path path = performSchematicWrite(clipboard, name);
final BlockVector3 origin = clipboard.getOrigin();
return new ArenaSchematic(path, origin);
} catch (final WorldEditException | IOException e) {
throw new AssertionError(e);
}
}

private static Clipboard performForwardExtentCopy(final Location[] corners) throws WorldEditException {
final CuboidRegion region = createRegion(corners);
final BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
final com.sk89q.worldedit.world.World world = region.getWorld();
final WorldEdit instance = WorldEdit.getInstance();
try (final EditSession session = instance.newEditSession(world)) {
final BlockVector3 min = region.getMinimumPoint();
final ForwardExtentCopy forwardExtentCopy = new ForwardExtentCopy(session, region, clipboard, min);
forwardExtentCopy.setCopyingEntities(true);
Operations.complete(forwardExtentCopy);
return clipboard;
}
}

private static Path performSchematicWrite(final Clipboard clipboard, final String name) throws IOException {
final Path data = IOUtils.getPluginDataFolderPath();
final Path parent = data.resolve("schematics");
IOUtils.createFolder(parent);

final Path file = parent.resolve(name);
final BuiltInClipboardFormat format = BuiltInClipboardFormat.SPONGE_V3_SCHEMATIC;
try (
final OutputStream stream = Files.newOutputStream(file);
final OutputStream fast = new FastBufferedOutputStream(stream);
final ClipboardWriter writer = format.getWriter(fast)
) {
writer.write(clipboard);
}

return file;
}

private static CuboidRegion createRegion(final Location[] corners) {
final Location first = corners[0];
final Location second = corners[1];
final World world = requireNonNull(first.getWorld());
final BlockVector3 firstCorner = BukkitAdapter.asBlockVector(first);
final BlockVector3 secondCorner = BukkitAdapter.asBlockVector(second);
final com.sk89q.worldedit.world.World instance = BukkitAdapter.adapt(world);
return new CuboidRegion(instance, firstCorner,  secondCorner);
}

public Path getSchematicPath() {
return this.schematicPath;
}

public BlockVector3 getOrigin() {
return this.origin;
}
}
Я пытаюсь импортировать эти объекты в базу данных встроенного сервера H2. У меня есть абстрактный класс Controller, который управляет моими классами менеджеров, такими как ArenaManager.

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

package io.github.pulsebeat02.murderrun.data.hibernate.controllers;

import static java.util.Objects.*;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public abstract class AbstractController implements Controller {

private final SessionFactory factory;
private final Object id;

public AbstractController(final SessionFactory factory, final Object id) {
this.factory = factory;
this.id = id;
}

@Override
public T deserialize() {
try (final Session session = this.factory.openSession()) {
final Transaction transaction = session.beginTransaction();
final Class clazz = this.getGenericClass();
final T manager = session.get(clazz, this.id);
final T defaultEntity = requireNonNull(this.createDefaultEntity());
final T returnEntity = requireNonNullElse(manager, defaultEntity);
transaction.commit();
return returnEntity;
} catch (final Exception e) {
throw new AssertionError(e);
}
}

public abstract T createDefaultEntity();

@Override
public void shutdown() {
if (this.factory.isOpen()) {
this.factory.close();
}
}

@Override
public void serialize(final T data) {
if (data == null) {
return;
}

try (final Session session = this.factory.openSession()) {
final Transaction transaction = session.beginTransaction();
session.merge(data); // error occurs here
transaction.commit();
}
}
}
Я использую предварительно заданные идентификаторы, потому что хочу установить идентификатор для каждого из моих менеджеров, например моего ArenaManager.

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

package io.github.pulsebeat02.murderrun.data.hibernate;

public interface HibernateIdentifiers {
Long LOBBY_ID = 1L;
Long ARENA_ID = 2L;
Long PLAYER_STATISTICS_ID = 3L;
Long LOBBY_MANAGER_ID = 4L;
Long ARENA_MANAGER_ID = 5L;
Long STATISTICS_MANAGER_ID = 6L;
}
Я даю своим пользователям возможность хранить данные либо в формате JSON, либо в базе данных, например H2, и формат сохранения JSON работает, но я пытаюсь выяснить, как это сделать через базы данных через Спящий режим. Я не хочу создавать новый набор абстракций данных Arena только для баз данных, я хочу использовать свой текущий менеджер и корректно аннотировать карту, чтобы она соответствовала строкам и столбцам моей базы данных H2.
Когда я пытаюсь обновить/сохранить свои данные в базе данных после того, как мой экземпляр ArenaManager был изменен или модифицирован пользователем (обычно посредством новых или удаленных записей в базовой карте), в итоге я получаю исключение, указанное выше.
Я пытался провести дальнейшее исследование других тем StackOverflow, форумов и задавал вопросы в различных Discord, но мне не удалось, потому что Я не уверен, что может быть источником этой ошибки. Я видел много других тем с этой же проблемой, но, похоже, я не могу отследить источник или причину по трассировке стека из-за отсутствия опыта. Было бы очень признательно, если бы кто-нибудь указал мне правильное направление. Спасибо.

Подробнее здесь: https://stackoverflow.com/questions/791 ... ntifier-ex
Ответить

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

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

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

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

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