JUnit с hibernate: этот экземпляр еще не существует как строка в базе данных - PullRequest
3 голосов
/ 15 декабря 2011

Я делаю тест с использованием JUnit.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/mt/sm/application-context.xml", "classpath:com/mt/sm/security-context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class LocationPathServiceImplTest { /* Class code here */ }

Объявление метода теста довольно простое:

@Test
public void testRefresh() { /* Method body */}

Я создал save obj в setup() и сохранить в БД.В то время как в @Test я запускаю refresh() из DAO (метод refresh () просто вызывает EntityManager .refresh ()), но это вызывает ошибку ниже

org.hibernate.HibernateException: this instance does not yet exist as a row in the database
javax.persistence.PersistenceException: org.hibernate.HibernateException: this instance does not yet exist as a row in the database

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

Ни при каких обстоятельствах я не фиксирую изменения в базе данных и не вызываю .flush ().Насколько я понимаю, они находятся в рамках текущей транзакции.

Ответы [ 3 ]

2 голосов
/ 15 декабря 2011

Без дополнительного кода, я бы сказал, вам нужно flush ваш DAO, чтобы экземпляр сохранился. refresh - это только уровень объекта, в то время как flush выполняет фактическую транзакцию на уровне базы данных (следовательно, rollback = true, поэтому он возвращается после теста)

1 голос
/ 15 декабря 2011

Я не уверен, что другие ответы о том, что вы должны flush(), верны, так как это ничего не передаст в базу данных.См. Документы Hibernate .При очистке сеанса данные, которые в данный момент находятся в сеансе, просто синхронизируются с данными в базе данных.Поэтому ваше исключение имеет смысл, если вы не вызвали myobject.save() в своем методе setUp ().

Я не думаю, что вы хотите вызывать commit() где-либо, потому что вы хотите, чтобы все откатывалось после завершения теста,Используйте эти аннотации для вашего Class

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) 
@Transactional

Затем вы можете добавить @before в свой метод setUp (), хотя, если ваш класс расширяет TestCase, это будет то же самое.Thor84no верен в том, что метод @before будет выполняться в той же транзакции, что и ваш метод @Test.Если вы на самом деле хотели заполнить базу данных зафиксированными данными, вы можете использовать метод, помеченный @beforeTransaction.

[РЕДАКТИРОВАТЬ]

Судя по обновленному вопросу, похоже, что вы этого не сделалиназывается persist() или похожим на объект, который, как вы говорите, вы создали в setup (), и он считается отсоединенным (т.е. не сохранен в базе данных в вашей транзакции).

0 голосов
/ 15 декабря 2011

Я бы также сбрасывал / закрывал / открывал сессию для принудительной записи в базу данных.

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