Posts

Showing posts from 2010

Intercepting and adjusting SQL generated by Eclipselink JPA

In some cases it might be useful to intercept and adjust the SQL generated by EclipseLink JPA. E.g. if you want to force an index in mysql you need to append force index (myindex) to the table name.

If you create a query on the entitymanager:

Query q = em.createQuery("select e from MyEntity");

you can cast it to the EclipseLink JpaQuery:

JpaQuery jq = (JpaQuery)q;

and the JpaQuery gives you access to the EclipseLink DataBaseQuery where you can prepare it before executing it:

DatabaseQuery dbQuery = q.getDatabaseQuery();
dbQuery.prepareCall(((org.eclipse.persistence.jpa.JpaEntityManager)em).getActiveSession(),new DatabaseRecord());

You can now get the sql string and add the forced index:

dbQuery.setSQLString(dbQuery.getSQLString()+" force index (myindex)");

and finally you can get the resultset using q.getResultList().

If you have parameters in the sql it's a bit more to it. Currently I've only found one option - probably not optimal since the query is translated to no…

EJB3 unit testing - part two - replacing the initialcontext

Some of your code might use EJB session beans through JNDI lookup. To make this code find your session beans in your unit tests, you can replace the initial context quite easily. This is an example of how it can be done.


public class ReplaceInitialContext extends InitialContext implements InitialContextFactory {

static ReplaceInitialContext instance = null;

public ReplaceInitialContext() throws NamingException {
super(false);
}

public static ReplaceInitialContext getInstance() throws NamingException
{
if(instance == null)
{
System.setProperty("java.naming.factory.initial",ReplaceInitialContext.class.getName());
instance = new ReplaceInitialContext();
}
return instance;
}

@Override
protected void init(Hashtable environment) throws NamingException {
}

@Override
public Object lookup(String name) throws NamingException {
return "Hello";
}

public Context ge…

EJB3 unit testing - part one - dependency injection

You might want to use an embeddable container for this - but why really - cause it's really simple. EJB3 session beans are POJO's and should be tested like POJO's.

However there are some issues in order to get EJB3 unit tests working. One of them are dependency injection.

How does dependency injection work? Take a look at this method using reflection:


/**
* @param targetBean - the bean to inject into
* @param annotationClass - the annotation class representing the injection
* @param objectToInject - the object to inject into targetBean
*/

private void inject(Object targetBean, Class annotationClass, Object objectToInject)
{
// Scan all (private and public fields) of the bean class
for(Field fld : targetBean.getClass().getDeclaredFields())
{
// See if the specified annotation is present for the field
if(fld.isAnnotationPresent(annotationClass))
{
// See if the field type is appropriate according to the object that is to be injected
if(fld.getType().isAssi…