Reputation: 61
I'm doing a test by using 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 */ }
The test method declaration is quite simple:
@Test
public void testRefresh() { /* Method body */}
I've created save an obj in the setup()
and save to db.
While in @Test
I run the refresh()
from DAO (the refresh() method just calls EntityManager .refresh()), but it causes me the error below
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
I have no idea how to fix it. Did anybody come across this before? All suggestions would be appreciated.
At no point I commit the changes to the database nor I call .flush(). For my best understanding, they are within the current transaction.
Upvotes: 4
Views: 4967
Reputation: 15879
I'm not sure the other answers saying you should flush()
are correct as this will not commit anything to the database. See Hibernate docs. Flushing the Session simply gets the data that is currently in the session synchronized with what is in the database. So your exception makes sense if you have not called myobject.save()
in your setUp() method.
I don't think you want to call commit()
anywhere either becasue you want everything to rollback after your test completes. Use these annotations on your Class
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
You can then add @before
on your setUp() method although if your class extends TestCase this will be the same. Thor84no is correct in that the @before method will execute in the same transaction as your @Test method. If you actually wanted to seed the database with commited data you can use a method annotated with @beforeTransaction
instead.
[EDIT]
Based on your updated question, it sounds like you have not called persist()
or similar on the object you say you have created in setup() and it's considered to be dettached (i.e. not persisted to the database within your transaction).
Upvotes: 1
Reputation: 12367
I would also flush / close / reopen session to force actual writing into database.
Upvotes: 0
Reputation: 10918
Without more code I'd say, you need to flush
your DAO so the instance gets persisted. refresh
is only object level while flush
does an actual transaction on database level (hence the rollback = true
so it gets rolled back after the test)
Upvotes: 3