Подтвердить что ты не робот

Org.hibernate.ObjectNotFoundException: не существует строки с указанным идентификатором, но она

У меня проблема спящего режима, которую я не могу исправить.

Настройка: Java EE, веб-приложение, Hibernate 3.2, Tomcat 6, Struts 2.

В основном, я сохраняю объект с помощью моей логики сервера (действие struts), затем попытаюсь вытащить эти данные для следующей страницы и отобразить их.

Я проверяю базу данных после сохранения объекта, и, конечно же, я вижу строку там со всеми данными.

Но когда я пытаюсь получить его, я получаю следующее:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [msc.model.Picture#73]

Чтобы сделать вещи еще более грязными, когда я перезапускаю Tomcat и пытаюсь получить доступ к одному и тому же объекту, я не получаю ошибку - Hibernate находит строку просто отлично.

Hibernate также сможет видеть строку, если я выполняю некоторые другие операции - возможно, добавьте строку здесь и там в базу данных, даже не в той же таблице.

Из всего этого я подозреваю ошибку Hibernate, но я новичок в Hibernate, поэтому я, вероятно, ошибаюсь. Пожалуйста помоги! Я googled и googled безрезультатно.

Вот моя конфигурация Hibernate:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/msc</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">-------</property>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">80</property>
        <property name="current_session_context_class">thread</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <mapping resource="msc/model/Picture.hbm.xml"/>
        <mapping resource="msc/model/Comment.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

Вот мои два файла сопоставления:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="msc.model.Picture" table="PICTURE">
    <id column="PICTURE_ID" name="id">
      <generator class="native"/>
    </id>
    <property name="story"/>
    <property name="email"/>
    <property name="category"/>
    <property name="state"/>
    <property name="ratings"/>
    <property name="views"/>
    <property name="timestamp"/>
    <property name="title"/>
    <property lazy="true" name="image" type="blob">
      <column name="IMAGE"/>
    </property>
    <property lazy="true" name="refinedImage" type="blob">
      <column name="REFINEDIMAGE"/>
    </property>
    <property lazy="true" name="thumbnail" type="blob">
      <column name="THUMBNAIL"/>
    </property>
    <bag cascade="save-update" lazy="true" name="comments" table="COMMENT">
      <key column="PICTURE"/>
      <one-to-many class="msc.model.Comment"/>
    </bag>
  </class>
</hibernate-mapping>

и

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="msc.model.User" table="USER">
    <id column="USER_ID" name="id">
      <generator class="native"/>
    </id>
    <property name="username"/>
    <property name="email"/>
    <bag cascade="save-update" lazy="true" name="pictures" table="PICTURE">
      <key column="USER"/>
      <one-to-many class="msc.model.Picture"/>
    </bag>
    <bag cascade="save-update" lazy="true" name="comments" table="COMMENT">
      <key column="USER"/>
      <one-to-many class="msc.model.Comment"/>
    </bag>
  </class>
</hibernate-mapping>

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, я рад помочь.

(обратите внимание: это не дубликат этого вопроса, сценарий не тот же "Нет строки с данным идентификатором существует" , хотя она существует)

РЕДАКТИРОВАТЬ: по запросу, размещение кода Java:

Код для сохранения объекта

Session hib_ses = HibernateUtil.getSessionFactory().getCurrentSession();

hib_ses.beginTransaction();

hib_ses.save(user);

hib_ses.getTransaction().commit(); 

Код для отображения данных (изображение в этом случае)

public class ImageAction extends ActionSupport implements ServletResponseAware, SessionAware {

    private HttpServletResponse response;
    Map session;
    private Long id;
    private int thumbnail;
    private InputStream inputStream;

    @Override
    public String execute() throws Exception {
        response.setContentType("image/jpeg");
        Session hib_session = HibernateUtil.getSessionFactory().getCurrentSession();
        hib_session.beginTransaction();

        //what is the ID now?
        Picture pic = (Picture) hib_session.load(Picture.class, getId());

        if (thumbnail == 1) {
            inputStream = (ByteArrayInputStream) pic.getThumbnail().getBinaryStream();
        } else {
            inputStream = (ByteArrayInputStream) pic.getRefinedImage().getBinaryStream();
        }

        hib_session.close();
        return SUCCESS;
    }
4b9b3361

Ответ 1

Проверьте все ваши сопоставления и настройки базы данных. Возможно, вы устанавливаете значение не-null = "true" в отношении внешних ключей, когда в базе данных указано значение nullable = "true". Первый вызывает INNER JOIN, а второй вызывает LEFT JOIN.

Установите уровень журнала в TRACE, чтобы увидеть все шаги и искать сгенерированный SQL при извлечении объектов.

Ответ 2

Это происходит потому, что вы вставили что-то, что предназначено для внешнего ключа, но ничего не ссылается. Проверьте свою базу данных, существует ли этот ключ или нет (даже если он находится в базе данных в других таблицах).

Ответ 3

Просто проверьте свою базу данных, доступен ли идентификатор 73 или нет в вашей конкретной таблице.

Ответ 4

Хорошо, я собираюсь выкинуть теорию здесь. Может быть, вы пытаетесь загрузить изображение в первый раз до совершения транзакции?

Поскольку транзакция еще не выполнена, строка не отображается для транзакции, которую вы используете для чтения изображения (зависит от того, какой уровень изоляции транзакции у вас есть).

Тогда, поскольку hib_session.close() не находится внутри блока finally, он не будет выполнен, и сеанс, связанный с потоком, все равно будет иметь открытую транзакцию. Следующий запрос получает тот же сеанс Hibernate, с той же открытой транзакцией, и вы получаете тот же результат от выбора, который он выдает (опять же, в зависимости от уровня изоляции транзакции - см. здесь, в частности для REPEATABLE_READ).

Это также может объяснить, почему flush() делает его немного лучше, потому что, если flush() встречается раньше, чем commit(), существует меньшая вероятность возникновения условия гонки.

Я предлагаю вам попробовать закрыть сеанс в блоке finally и посмотреть, изменится ли поведение для последующих запросов.

Ответ 5

Во многих отношениях вам нужно сообщить Hibernate, что нужно сделать, если отображаемая строка не найдена. Вы можете настроить его следующим образом:

Annotation:
@NotFound(action = NotFoundAction.IGNORE)
Mapping XML:
<many-to-one name="user" column="user_id" class="com.xyz.User" cascade="save-update, evict" not-found="ignore"/>

Ответ 6

Я не вижу никаких реальных проблем, связанных с исключением в коде, вы можете попробовать:

  • Проверка того, что транзакция сбрасывается или вызов flush() вручную после совершения транзакции;
  • Проверка того, передан ли идентификатор в load() и передан ли ему правильный идентификатор через отладчик
  • Включение Hibernate для печати созданного SQL и/или включения ведения журнала

Ответ 7

У меня есть аналогичная проблема с hibernate 3.6.10, в то время как я просто ищу и выбираю (если есть).

Аннотация:

@Entity
public class Familiares {
@OneToMany(mappedBy = "familiares")
private List<FamiliaresBaja> bajas;

@Entity
@Table(name = "familiares_baja")
public class FamiliaresBaja implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @JoinColumn(name = "familiares_id")
    @ManyToOne(optional = false)
    private Familiares familiares;

то я получаю список и с этим глядя в FamiliaresBaja, если есть хотя бы один.

createQuery("from FamiliaresBaja where familiares.id="+ id).uniqueResult() // should return a single result or null not throw a Exception

Это должна быть ошибка Hibernate

Ответ 8

Пожалуйста, проверьте значение lower_case_table_names вашего сервера mysql. Если его значение равно 0, проверьте SQL, сгенерированный с помощью hibernate, убедитесь, что регистр имени таблицы соответствует фактическому имени таблицы в mysql.

Ответ 9

Я столкнулся с этой проблемой, и вот что случилось и как я решил ее. Скорее всего, у вас тоже самое происходит.

У меня были объекты POST и USER. Они находятся в отношениях OneToMany (пользователь может иметь много сообщений). Делая это двунаправленным, они также находятся в отношениях ManyToOne (один пост принадлежит только одному пользователю).

Сообщение класс выглядит

@Entity
@Table(name="Post")
public class Post {

@Id
@GeneratedValue(strategy=GenerationType.TABLE)
private long postId;
private String title;
private String body;

@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "postUserId")
private AutoUser autoUser;
// getter and setters

Пользовательский класс

@Entity
@Table(name = "AUTO_USER")
public class AutoUser implements UserDetails {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long autoUserId;

@Column(name = "USERNAME")
private String username;

@OneToMany
private List<Post> postList = new ArrayList<>();
  // getter and setters

Первые имена таблиц были Post и AUTO_USER. У меня было 3 пользователя, сохраненных в таблице AUTO_USER (с идентификаторами 1, 2, 3). И 3 записи в таблицу Post 1 для каждого пользователя. (столбцы соединения или внешний ключ были 1, 2, 3)

Затем я изменил только имя таблицы только для объекта пользователя и назвал его @Table(name = "AUTO_USER2"). и у меня был только один пользователь в этой таблице с идентификатором 1.

В моем коде я перебираю каждое сообщение и определяю, какое сообщение принадлежит какому-либо пользователю, и отображаю их, которые принадлежат текущему зарегистрированному пользователю.

После изменения названия таблицы сообщений я получил это исключение

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tadtab.core.authentication.AutoUser#2

Что говорит мне, что пользовательский объект с идентификатором 2 недоступен в новой пользовательской таблице.

тогда я зарегистрировал еще одного пользователя с идентификатором 2 и позже я получил это

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tadtab.core.authentication.AutoUser#3

На этот раз он не смог найти пользователя с идентификатором 3

Наконец-то зарегистрировался третий пользователь и не стал исключением.

Как видите, внешний ключ существует в таблице записей, но, поскольку я изменил таблицу пользователей, для них не может быть совпадений, и именно поэтому я столкнулся с этой проблемой.

Чтобы избежать этой ситуации, я создал новые имена таблиц для обоих объектов и начал заново

Надеюсь, это поможет

Ответ 10

Это исключение возникает, когда Session.load() не может выбрать строку с заданным первичным ключом (значение идентификатора). Это исключение может не возникать при вызове load(), даже если в базе данных не было строк, поскольку load() возвращает прокси-сервер, если это возможно. Приложения должны использовать Session.get(), чтобы проверить, существует ли строка или конкретная запись в базе данных для определенного первичного ключа.

В этой статье мы обсуждаем hibernate org.hibernate. ObjectNotFoundException: строка с указанным идентификатором не существует.

Причина Это исключение выдается, когда вы пытаетесь загрузить сущность в режиме гибернации с помощью метода session.load(), и сущность не найдена, что означает, что экземпляр конкретной сущности не найден в текущем контексте перехода в режим гибернации.

Трассировка исключения выглядит так:

Hibernate: select employee0_.ID as ID0_0_, employee0_.NAME as NAME0_0_ from employee employee0_ where employee0_.ID=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [hibernate.test.dto.EmployeeEntity#11]
at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:375)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:79)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:68)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:140)
at hibernate.test.dto.EmployeeEntity$$EnhancerByCGLIB$$deac2c14.getName()
at hibernate.test.TestHibernateEhcache.main(TestHibernateEhcache.java:17)

Решение Правильный способ решить эту проблему - использовать метод session.get(). Метод Get вернет значение NULL, если для этой сущности нет записи повторно или если запись не найдена.

Employee emp = (Employee) session.get(Employee.class, new Integer(11));

//This will throw NullPointerException if entity is not found.

System.out.println(emp.getName());

Еще одно решение состоит в том, чтобы вызвать session.load() в блоке try catch и обработать исключение соответственно. Для получения более подробной информации нажмите на ссылку: https://www.quora.com/How-can-I-do-to-automatics-reset-auto-increment-values-in-MySQL-table/answer/Shadab-Kazi- 17