admin管理员组

文章数量:1122832

I have 3 tables:

  • instances

  • instance_members

  • instance_invitations

where "Instance" has an @OneToMany relationship to "InstanceMember" and "InstanceInvitation" and the two have a "@ManyToOne" relationship back towards "Instance":

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<InstanceMember> members = new ArrayList<>();

@OneToMany(mappedBy = "instance", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<InstanceInvitation> invitations = new ArrayList<>();

@Column(name = "created_at")
private LocalDateTime createdAt;

@Column(name = "updated_at")
private LocalDateTime createdAt;

InstanceMember

@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;

InstanceInvitation

@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;

The program allows the user to invite another user towards their instance, which the target may accept or reject:

  • On invitation creation, an entry in "instance_invitation" is created

  • If it is accepted, the entry in "instance_invitations" is deleted and another is created in "instance_members"

  • If it is rejected, the entry in "instance_invitations" is deleted and no member relationship is created

This works fine if User A only interacts with User B.

If User A decides to remove an existing User using the "kick" functionality (Which only deletes the entry in "instance_members"), everything works fine as well.

If User A decides to invite User C after User B has been removed, the program crashes and hibernate throws the following errror:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [me.test.game.model.InstanceMember#f9b56403-46a4-465b-a459-3de54e4abea8]


The following code is used to persist (Create new entry) an entity towards the session:

protected void persistToSession(@Nonnull T data, @Nonnull DatabaseCallback<T> 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()mit();

        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);

}

The following to update an existing one:

public void update(T data, DatabaseCallback<T> callback) {

    Session session = null;

    try {

        data.setUpdatedAt(LocalDateTime.now());

        session = getSessionFactory().openSession();
        session.beginTransaction();
        session.merge(data);
        session.getTransaction()mit();

        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();
        }
    }

}

The following to delete:

public void delete(T data, DatabaseCallback<T> callback) {

    try (Session session = getSessionFactory().openSession()) {
        session.beginTransaction();
        session.remove(data);
        session.getTransaction()mit();

        callback.onQueryDone(data);

    } catch (Exception e) {
        Main.log(this.getClass(), LogType.ERROR, "Error on DELETE of model '" + tClass.getName() + "': " + e.getMessage());
        callback.onQueryDone(null);
    }

}

The interface DatabaseCallback is just used for async operations in the codebase:

public interface DatabaseCallback<T> {

    void onQueryDone(T result);

}

Every operation works fine on itself, but somehow i run into inconsistencies, although i use foreign key constraints and relationship mappings with orphanRemoval.

The error states that no row with the given identifier could be found, which is correct, as it has been deleted in a previous transaction that has already been completed. After successfully callback of the deletion i remove the entry in the corresponding list ("members" or "invitations" on the "Instance" model) manually.

My question is the following: Where does hibernate get the information from, that the object could not be found? The deletion query was successful and the entry therefore does no longer exist, why does hibernate still know about it?

I tried debugging the hibernate SQL queries, but they only return what I already know: Hibernate assumes that a member still exists, although it has been deleted in a previous transaction.

Update 23th November:

  • I removed the "delete" operations and just remove the member from the instance's member list and then update the whole object towards the database: No changes. The first operation works perfectly fine, the second one raises the same error.

本文标签: javaHibernate ObjectNotFoundException No row with the given identifier existsStack Overflow