views:

93

answers:

4

I'm working with many classes which are annotated with javax.persistence.Entity and the like. My project is about generating metadata about JPA-annotated classes rather than persistence by itself, so I'm using them as test cases.

Rather than firing up Hibernate or some other JPA provider, I'd like to programatically check - part of my unit tests - that my JPA declarations are indeed valid.

What's the easiest way of doing that?

A: 

I'm not sure if there's an easier way but you can use Reflection to access the annotations of a class

Class class = Example.class;
Annotation[] annotations = class.getAnnotations();
royalsampler
That would be the easy part. Validating all annotations are valid is the difficult one.
Willi
I agree with @Willi . I want to validate using them, but fear the overhead of starting up a provider for my unit tests.
Robert Munteanu
+2  A: 

Just create the simplest possible SessionFactory or whatever EclipseLink or OpenJPA provide behind the EntityManagerFactory and let them validate it (using some dummy in-memory database, if needed). It's too complex to reinvent it.

For Hibernate this can be done using Configuration.buildMappings:

@RunWith(Theories.class)
public class EntitiesAreValidTest {

    @DataPoints
    public static Class<?>[] entities = new Class[] {
        SimpleEntity.class,
        SimpleEntityWithTransientField.class,
        TwoFieldEntity.class
    };

    @Theory
    public void classHasValidConfiguration(Class<?> entityClass) {

        new AnnotationConfiguration().addAnnotatedClass(entityClass).buildMappings();
    }
}
Bozho
A: 

Whats wrong about using a concrete JPA-provider in your tests? In combination with an embedded database (e.g. Apache Derby) you could reuse logic that has indeed already been implemented. Another idea would be to check the sources of EclipseLink, Hibernate, OpenJPA, ... to see whether you can directly use it.

Willi
Spped basically - I want my unit tests to be fast. Hibernate startup can be costly.
Robert Munteanu
My unit tests are usually being executed on a build server, so performance is no issue. Already considered TeamCity or something similiar?
Willi
@Wili Speed is an issue at some point, even when test are executed on a CI server.
Pascal Thivent
A: 

If you don't trust JPA providers (or don't want to use them) then try to reconcile JPA annotations (metadata) retrieved using reflection with JDBC metadata retrieved using ResultSetMetaData (for example see here).

I don't mean this to be simple, but with right approach you should have rather compact set of helper methods to check basic definitions for each entity. And mileage may vary depending on how much JPA functionality you want to cover.

grigory