Сохранение с использованием Hibernate / JPA - PullRequest
3 голосов
/ 12 ноября 2008

Я работаю с hibernate / JPA на JBoss уже несколько месяцев, и у меня есть один вопрос, на который я не могу найти ответ или решение.

Похоже, что при создании новых бинов сущностей я не могу выполнить запрос до того, как по крайней мере вызову EntityManager.persist (entityBean), иначе я получаю следующую ошибку:

TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

Пример:

Job job = new Job();
Collection<Task> tasks = job.getTasks();
//entityManager.persist(job);
ActionPlan actionPlan = (ActionPlan) entityManager.createNamedQuery("ActionPlan.findByCommand").
                setParameter("type", RunOperation.Install).getSingleResult();
Task task = Task.getTask(actionPlan);
task.setActionPlan(actionPlan);
tasks.add(task);
task.setJob(job);

Моя проблема в том, что я не могу вызвать createNamedQuery без предварительного сохранения «задания» (закомментированной строки). ActionPlan имеет отношение к Job, но NamedQuery (findByCommand) не включается в Job. Что меня беспокоит, так это то, что мне нужно сохранить Job, чтобы запрашивать базу данных, когда вновь созданное Job даже не интересно в этом контексте.
Перемещение вызова функции persist () в конец фрагмента приводит к вышеупомянутой ошибке.

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

Я считаю, что есть решение для этого, поэтому, если у кого-то есть ответ, я был бы очень благодарен. Чего мне не хватает?

Ответы [ 4 ]

3 голосов
/ 12 ноября 2008

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

P.S. Здесь внизу вы можете найти «Типичная транзакция должна использовать следующую идиому».

Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
    //do some work
    ...
    tx.commit();
}
catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
}
finally {
    sess.close();
}
0 голосов
/ 13 ноября 2008

Ну, я думаю, что ответы и чтение в руководстве по Java EE 5 дали мне правильный ответ.

Вопреки моему убеждению, persist () не не сбрасывает данные в базу данных, а только переводит компонент Entity в постоянное состояние. Меня обмануло то, что я заметил, что после вызова persist сущность фактически все равно сохраняется в базе данных (и, возможно, в сообщении об ошибке есть слово «save»). Я воспринял это как вызов flush, завершивший мою транзакцию, но если я правильно понял themalkolm, я все еще могу выполнить откат - самостоятельно или с сервера при исключении.

Итак, мой вывод таков; persist следует просто вызывать всякий раз, когда создается новая сущность, если она не связана с другой сущностью, которая уже существует.
Затем транзакция сохраняется, и сервер любит вас немного больше;)

Что ей осталось, так это то, что я до сих пор не понимаю, почему я не могу сделать запрос, если все не находится в постоянном состоянии.

0 голосов
/ 13 ноября 2008

Даже если вы сохраняете объект, вы все равно можете откатить его. Только после вызова сброса в EntityManager будет происходить синхронизация случая с базовой базой данных.

0 голосов
/ 12 ноября 2008

Мне известно, что я не могу запросить то, что еще не было сохранено - и это тоже не так. То, что я хочу найти, это другие бины сущностей. Не только тот же тип, но любой тип компонентов Entity, которые у меня есть. И тогда я получаю TransientObjectException.

Я упоминал, что использую JBoss? Я считаю, что с помощью J2EE и JPA сервер контролирует мои транзакции, и последнее, что я хочу сделать, это помешать ему ?! Так что для меня, кроме использования requireNew и т. Д., Я не связываюсь с транзакциями - сервер делает.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...