user1999453
user1999453

Reputation: 1423

No transactional EntityManager available

I am new to the jpa and spring world and I am currently doing some unit test on a simple method but keep getting this error message only when I run my test class in unit test mode:

java.lang.IllegalStateException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:223)
at $Proxy19.unwrap(Unknown Source)
at com.gemstone.integration.PersonDao.getPersonByUserNamePassword(PersonDao.java:59)
at com.gemstone.integration.PersonDaoTest.getPersonByUserNamePassword_Exist(PersonDaoTest.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

However the code works fine when i run my project it retrieves the data correctly(Not in unit test mode).

Please find below my method which the unit test will be based on:

@PersistenceContext
private EntityManager entityManager;
@SuppressWarnings("unchecked")
public boolean getPersonByUserNamePassword(String firsName, String password) {

    String hql = "from Person p where p.firstName = :firsName and p.password =:password";
    Session mysession = entityManager.unwrap(Session.class);

    Query query = mysession.createQuery(hql);
    query.setParameter("firsName", firsName);
    query.setParameter("password", password);
    List<Person> results = query.list();

    if (results != null && results.size() > 0) {

        return true;
    }
    return false;

}

My unit test below:

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:/Intcontext.xml" })

public class PersonDaoTest {

    @Autowired
    PersonDao personDao;

    @Transactional
    @Test
    public void getPersonByUserNamePassword_Exist() {

        String firsName = "Andy";
        String password = "123";

        boolean isUserExists = personDao.getPersonByUserNamePassword(firsName,
                password);

        Assert.assertTrue(isUserExists);
    }

}

Any ideas why i am getting No transactional EntityManager available error please?:(

thanks in advance.

Upvotes: 5

Views: 10623

Answers (3)

Basheer AL-MOMANI
Basheer AL-MOMANI

Reputation: 15327

I got a similar problem when I try the unit tests with IntelliJ, even though its working using cli of maven-surefire-plugin

it turns out that IntelliJ build was using javac compiler and even though it specified in pox.xml to use ajc compiler there is a reported bug for IntelliJ at IDEA-135483

that made @Transactional not working and give you No transactional EntityManager available

if that is your case, you need to change java compiler to use ajc instead of javac and post-compile weave mode in project structure

Upvotes: 0

Sam Brannen
Sam Brannen

Reputation: 31177

By declaring

@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })

you have completely (albeit unintentionally) disabled support for test-managed transactions. The reason is that you have omitted TransactionalTestExecutionListener from the list of declared listeners.

Note, however, that TransactionalTestExecutionListener is declared transparently by default. Thus, when you delete your @TestExecutionListeners declaration from your test class, TransactionalTestExecutionListener is once again enabled.

You can of course find details in the Spring Reference Manual here.

Regards,

Sam (author of the Spring TestContext Framework ;) )

Upvotes: 5

9ine
9ine

Reputation: 859

I think EntityManager is null.Try Like this,may be it work

private EntityManager entityManager = null;

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
    this.entityManager = entityManager;
}

Upvotes: 2

Related Questions