Save method - не очищает сеанс после возникновения исключения
public class SoftwareTest extends UnitTest {
@Before
public void setup() {
Fixtures.deleteAll(); // will fail if comment that. why?????
}
@Test
public void createSoftwareWithNullAuthor() {
// when author is null
Author nullAuthor = null;
Software software = new Software("software1", "description1", nullAuthor);
try {
software.save();
fail("author should not be null");
} catch (PersistenceException ex) {
}
}
@Test
public void createSoftwareWithOkAuthor() {
// when author is ok
Author okAuthor = new Author("author1", "email1").save(); // ERROR HERE!
Software software2 = new Software("software2", "description2", okAuthor);
Software savedSoftware = software2.save();
assertNotNull(savedSoftware);
assertEquals(savedSoftware, software2);
assertNotNull(savedSoftware.author);
assertEquals(okAuthor, savedSoftware.author);
}
}
при раскомментировании строки с Fixtures.deleteAll()
мы получим исключение во втором методе - createSoftwareWithOkAuthor()
, когда save()
автор. Почему это произошло?
org.hibernate.AssertionFailure: null id in models.Software entry (don't flush the Session after an exception occurs)
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:82)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:190)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:147)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:240)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
Ответы
Ответ 1
проблема заключается в том, что Hibernate вызывает исключение (поэтому текущая транзакция становится недействительной), но затем вы пытаетесь продолжить больше операций в этом сеансе.
Правильный способ сделать это - разбить тест, который вы используете в 2, на одну часть для проверки нулевых авторов, а другой - на проверку подлинным автором.
В производственном коде (скажем, контроллер) вам нужно будет перезапустить операцию (закройте транзакцию, перезапустите процесс), чтобы продолжить. Но учитывая, как игра управляет транзакциями, нормальное поведение будет заключаться в том, что после ошибки вы просто вернетесь с сообщением об ошибке пользователю.
Ответ 2
Из ошибки:
org.hibernate.AssertionFailure
: null id
в записи models.Software
(не очищайте Session
после возникновения исключения)
Мы видим, что исключение сеанса произошло до. Точка, в которой выбрана эта org.hibernate.AssertionFailure
, не является точкой, где возникла ошибка.
То есть: Что-то подавляет исходное исключение.
Поэтому ищите другие возможные точки ошибки. A save()
или saveOrUpdate()
, возможно, пытается сохранить объект с полем null
, где в таблице столбец NOT NULL
.
В моем случае исключение real происходило внутри блока try/catch {}
, где catch
подавляло исключение (не ревертировало или не предупредило меня об этом).
Ответ 3
Возможно, кто-то повторит мою ошибку:
Я также сталкиваюсь с этой проблемой. В моем случае проблема возникла из-за того, что я установил column
type integer
и попытался написать значение long
. После изменения типа column
он начинает работать.