Running tests with EJB Container and JPA - java

I'm suffering in understanding how to properly set up tests in JUnit for EJB and JPA. I've seen advices telling to use Arquillian for the integration test, but I want to do a simple unit test.
What I have right now is a EJB with injects a Persintance Context. I run the application in Wildfly 9 and have the datasource configured there, so my persistance file looks like this:
<jta-data-source>java:jboss/datasources/MyDataSource</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
</properties>
Now if I added glassfish-embedded-all to my test dependencies to run the embeded EJB container and created a simple test:
Map<String, Object> properties = new HashMap<>();
properties.put(EJBContainer.MODULES, new File("target/classes"));
EJBContainer container = EJBContainer.createEJBContainer();
TestEJb bean = (TestEJb) container.getContext().lookup("java:global/classes/TestEJb");
assertNotNull(bean);
assertEquals(1,bean.test());
Then I receive the error as the EJB contains the refence to the MyDataSource which is not known by the container. Should I create another persistance unit and pass it somehow to the EJB?
What is the right way to do it?

The issue here is that you don't have an application context so the lookup is failing. Usually for unit testing container resources you use a mock object such as mockejb.
Lots of examples out there if you search for mockejb examples.

Related

Accessing a remote ejb from spring

I have an old spring app, and I want to update it to use a jndi looked up ejb.
The old spring app has a config file defining beans like so :
<bean id="myBean" class="uk.co.mycompany.mypackage">
<property name="dependentDao" ref="myOtherDaoBean"/>
</bean>
In my new applications I use ejbs to looked up like so :
#EJB(lookup = "java:global/myApp/myModule/MyOtherDaoBean!uk.co.mycompany.mypackage.MyOtherDaoBeanImpl")
private MyOtherDaoBean myOtherDaoBean;
How can I specify the spring app to use the new way ? I can include the bean interfaces as a dependent jar, but I want the runtime instance looked up using jndi.

ResourceLocal to JTA

I am developing an web application and I have to use JTA which I never used. I started using EntityManager but it seems not to work here. When I use EntityManager I get this message:
Only persistence units with transaction type JTA can be used as a container managed entity manager.
To cut it short, I have this piece of code:
#PersistenceContext(unitName = "zJSF2PU")
private EntityManager em;
em.getTransaction().begin();
//some code
em.getTransaction().commit();
How can I do this without EntityManager?
In your ejb project META-INF/persistence.xml you must have something like:
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<persistence-unit name="myPersistenceUnitNamePersonalised" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/MySQL</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="FINE" />
</properties>
</persistence-unit>
</persistence>
And you must declare this in your Application Server (jboss, tomcat, glassfish)
You need to search how to add a data-source and persistence unit in your Application Server...
And that's it... they comunicate thru jndi
Remove transaction-type="RESOURCE_LOCAL" from your persistence.xml.
Remove calls to em.getTransaction(). Inject javax.transaction.UserTransaction (JTA) and use its begin/commit/rollback methods. Alternatively, inject the EM into a stateless EJB instead, and allow the EJB container to automatically manage the transaction.
I finally was able to fix my problem. From my searches it resulted that you can not use EntityManager when you are using JTA within ManagedBeans for example. However it can be used in a stateless bean and then we can inject this Stateless Bean to the ManagedBean and use its methods. The procedure is as follows:
create an EJB (a simple class with #Stateless annotation)
move the method that uses EntityManager to the EJB
inject the EJB into your managed bean (using #EJB annotation) and call the relevant method
For more information refer to this other post: JTA & MySQL

Advice on how to refactor spring mvc into plain servlets or jetty handler

I have a spring mvc app that I want to refactor out, speficially removing the spring related code and wiring.
It is a simple spring mvc at this point, so the key things I have to do our dependancy injection.
My application.xml has wirings for my Dao objects, injecting the datasource into my Dao objects.
How can I use a spring agnostic DI now? What do I have to change? I want to use guice unless you guys recommend otherwise
application.xml:
<bean id="userDao" class="com.blah.dao.UserDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
What do you suggest I use to setup my datasource and connection pooling now?
The actual page/url mapping is specific to if I choose servlets or a jetty handler.
You can use the standard annotation #Inject for dependency injection. Both Spring and Guice support it.

How do I swap a jndi datasource lookup to an in memory database for intergration testing?

I'm using Spring and Hibernate and want to do some intergration testing with DBUnit. In my application-context.xml I currently specify a datasource via jndi-lookup which reads the jndi-name from a properties file:
<jee:jndi-lookup id="dataSource"
jndi-name="${datasource.myapp.jndi}"
cache="true"
resource-ref="true"
proxy-interface="javax.sql.DataSource" />
I'd like to swap this out to an in memory database (hsqldb, h2 etc) for integration testing by just supplying a new properties file, is this possible? Or should I just use a different application-context.xml for the integration testing?
You can either have separate application contexts for prod and test or specify a default data source for the JNDI data source that should be used if the lookup fails. Then don't have a JNDI data source configured on your integration test environment. Spring will automatically fail over to the in-memory source when the lookup fails.
This is why Spring 3.1 introduced profiles: http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/
Upgrade application to 3.1 or use different configs for integrations tests.
Move the datasource bean definition to a separate config file (infrastructure-config.xml), create another version of it called test-infrastructure-config.xml in which you can define a datasource either using the jdbc:embedded-database tag
<jdbc:embedded-database type="hsql">
<!-- in case you want to populate database, list the sql script files here -->
<jdbc:script location=".."/>
<jdbc:script location=".."/>
</jdbc:embedded-database>
Once you do this you specify the main application-context.xml and test-infrastructure-config.xml for out of conatiner testing and with the infrastructure-config.xml for deployment.
Use a #Bean to define your datasource. In that method you can use conditional logic to determine the environment and either do the JNDI lookup or connect to your in-memory DB.

Out of container JNDI data source

I would like to configure a DataSource using JNDI in a Java SE app. What is the best way to do this?
So far, I've come across 2 projects:
Apache Naming. The project page has a specific example for configuring a data source, but it looks like the project is super old and no longer active.
JBossNS. It looks like it's easy to configure a local-only JNDI using LocalOnlyContextFactory, but I haven't found any docs on how to actually configure a data source.
If possible, I would like to also configure the data source with a JTA transaction manager (using JOTM?).
Why are you using JNDI for this? It's not that it's a bad solution if you have a provider but there are alternatives such as dependency injection (IoC: via Spring or Guice).
The Spring JDBC data access is described here. The great thing is that you can use Spring to inject a DataSource into your code:
<bean class="com.my.Persister">
<property name="dataSource" ref="dataSource" />
</bean>
The data source can be defined using a JNDI-lookup:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
In a test environment, you could inject the data source directly:
<bean id="dataSource" class="apache.db.PoolingDataSource">
<!-- config goes here -->
</bean>
These references are pretty old but may help to use jnpserver (JBoss Naming Service provider):
Working With JNDI In A J2SE Application
Standalone JNDI server using jnpserver.jar
A very easy to use solution for stand-alone JNDI is simple-jndi. It works like a charm as long as you only need it within a single JVM, since it's a library no network server.
The Simple-JNDI version, referenced by klenkes74, is not under active development any more. Because I encountered some issues with it I forked it, did some bug fixes and implemented some new features. I already used the old version not only for testing but in production too because I prefer a Service Locator pattern over Dependency Injection although the latter one is more trendy nowadays.
You can easily use Simple-JNDI to define a DataSource or a connection pool declaratively and get it bound to a JNDI Context.
Define a jndi.properties file in your classpath:
java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=[absolute_or_relative_path_to_a_property_file]
The property file looks like:
type=javax.sql.DataSource
driver=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost/testdb
user=testuser
password=testing
Now you can access your DataSource from inside your code this way:
InitialContext ctxt = new InitialContext();
DataSource ds = (DataSource) ctxt.lookup("name_of_your_datasource");
For more information see https://github.com/h-thurow/Simple-JNDI

Categories

Resources