IllegalStateException LogicalConnectionManagedImpl закрыт в режиме гибернации

#java #hibernate #h2

#java #спящий режим #h2

Вопрос:

Я использую базу данных H2 с режимом гибернации на JAVA, и я получаю странную ошибку. Я создал свой абстрактный репозиторий для управления базовой операцией CRUD.

Исключение, которое я получаю, заключается в следующем:

 java.lang.IllegalStateException: org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@d20d74a is closed
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.errorIfClosed(AbstractLogicalConnectionImplementor.java:37)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:135)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:254)
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:116)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.rollback(JdbcResourceLocalTransactionCoordinatorImpl.java:294)
at org.hibernate.engine.transaction.internal.TransactionImpl.rollback(TransactionImpl.java:139)
at repositories.AbstractRepository.save(AbstractRepository.java:32)
at services.ResultService.saveResult(ResultService.java:76)
at services.API.WebRequestService.run(WebRequestService.java:124)
at services.API.ThreadService.run(ThreadService.java:67)
  

Метод сохранения абстрактного местоположения:

 public <T> T save(T t) {
    Transaction transaction = null;
    try (Session session = HibernateConfig.getSessionFactory().openSession()) {
        transaction = session.beginTransaction();
        Serializable entityId = session.save(t);
        transaction.commit();

        T createdEntity = (T) session.get(t.getClass(), entityId);
        return createdEntity;

    } catch (Exception e) {
        if (transaction != null) {
            transaction.rollback();
        }
        e.printStackTrace();
    }
    return null;
}
  

Я студент CS, и я не очень хорошо знаком с Hibernate. Я не получаю эту ошибку на своем компьютере, только на других компьютерах с созданным файлом JAR.

P.S Английский не мой основной язык, поэтому мне очень жаль, если вы меня не понимаете!

Ответ №1:

После нескольких часов отладки я обнаружил ошибку! Ошибка заключалась в том, что столбец превысил длину, и исключение исходило из блока catch. Блок catch пытался откатить что-то, что его соединение уже было закрыто. Я надеюсь, что это будет кому-то полезно!

Ответ №2:

Я получил ту же ошибку при попытке создать встроенную связь между двумя таблицами с использованием гибернации версии 5.5.3. Да, приведенный выше ответ был полезен для меня, чтобы отладить ошибку за один раз. Спасибо @William. То же самое было и в моем случае, блок catch пытался откатить транзакцию из-за исключения, возникшего в встраиваемом классе. Проблема заключалась в том, что у меня не было конструктора по умолчанию внутри встраиваемого класса.

Спасибо!

Ответ №3:

ответ @Vikarm и ответ @William указали мне правильное направление. Вам просто нужно создать свой составной идентификатор в конструкторе класса, который имеет EmbeddedId.

Вот как это выглядит в коде (полный пример включен для полноты картины)

 @Entity(name = "artwork_rating")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class ArtworkRating {
    @EmbeddedId
    private ArtworkRatingKey id; // This needs to be instantiated*

    private int score;

    private String content;

    // --------- Relations --------- //
    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name = "user_id")
    User user;

    @ManyToOne
    @MapsId("artworkId")
    @JoinColumn(name = "artwork_id")
    Artwork artwork;

    // --------- Constructors --------- //
    public ArtworkRating(int score, String content, User user, Artwork artwork) {
        this.id = new ArtworkRatingKey(user.getId(), artwork.getId()); // *as shown here
        this.score = score;
        this.content = content;
        this.user = user;
        this.artwork = artwork;
    }
}