Note that there are some explanatory texts on larger screens.

plurals
  1. POJUnit hibernate: testing lazy associations fetched
    primarykey
    data
    text
    <p>I have a User model with a lazily-loaded Sites collection:</p> <pre><code>@Entity public class User { @Id @GeneratedValue private Integer id; @OneToMany(fetch = FetchType.LAZY) private Set&lt;Site&gt; sites; ... </code></pre> <p>and a HQL query in my UserDao which loads a user by id, and also fetches the associated sites:</p> <pre><code>import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Query; import org.springframework.stereotype.Repository; @Repository public class userDaoImpl implements UserDao() { @Inject private SessionFactory sessionFactory; public Session getCurrentSession() { return sessionFactory.getCurrentSession(); } public User findByIdFetchSites(final Integer id) { String queryString = "SELECT user FROM User user LEFT JOIN FETCH user.sites WHERE user.id = :id"; Query qry = getCurrentSession().createQuery(queryString).setInteger("id", id); return qry.uniqueResult(); } ... </code></pre> <p>I want to test that the sites are being fetched along with the user when I run this Dao method. I have a JUnit test class running against HSQLDB, as follows:</p> <pre><code>@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath:/test-context.xml" }) @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) @Transactional public class UserDaoImplTest { @Inject private UserDaoImpl userDaoImpl; @Test public void retrievesUserFetchesSites() { Set&lt;Site&gt; sites = new HashSet&lt;Site&gt;(); ... User user = new User(); user.setSites(sites); userDaoImpl.saveOrUpdate(user); User retrievedUser = userDaoImpl.findByIdFetchSites(1); assertTrue(retrievedUser.getSites().containsAll(sites)); } </code></pre> <p>Where @Transactional is the spring transactional annotation (org.springframework.transaction.annotation.Transactional). The test passes even when I run it against a simple findUserById DAO method, for which the sites are not explicitly fetched:</p> <pre><code>public User findById(final Integer id) { String queryString = "SELECT user FROM User user WHERE user.id = :id"; Query qry = getCurrentSession().createQuery(queryString).setInteger("id", id); return qry.uniqueResult(); } </code></pre> <p>I'm not entirely sure why the sites are being fetched before the assertion (I can't see it in a select statement in the logs), but what I think I want to do is close the current session before the assertion occurs; something like:</p> <pre><code>@Test public void retrievesUserFetchesSites() { Set&lt;Site&gt; sites = new HashSet&lt;Site&gt;(); ... User user = new User(); user.setSites(sites); userDaoImpl.saveOrUpdate(user); User retrievedUser = userDaoImpl.findByIdFetchSites(1); userDaoImpl.getCurrentSession().close(); assertTrue(retrievedUser.getSites().containsAll(sites)); } </code></pre> <p>However, when I tried this I got the following exception:</p> <pre><code>org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: rollback failed at org.springframework.orm.hibernate4.HibernateTransactionManager.doRollback </code></pre> <p>which I assume is due to @DirtiesContext (I need a clean db before each test). How can I ensure that hibernate doesn't do lazy loading for my associations during the test?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload