Here is my take at configuring Spring programmatically to support the more popular JPA providers out there: Hibernate, EclipseLink, OpenJpa and DataNucleus.

I am assuming you already know how to programmatically configure a data source, as well as how to use the @Configuration annotation. I’m just providing the @Bean definition for the entity manager factory.

Shared code

The following bean definition code provides common code shared by all JPA providers, and then calls configureProvider: we will isolate all provider specific code in that method.

With this configuration you will have to provide your persistence.xml file. Just do not put a <provider> entry there: it will not be needed, we are specifying the provider programmatically.

However, if you want to remove the persistence.xml file, you can do that by specifying the packages to scan for entities programmatically, calling result.setPackagesToScan.

EclipseLink configuration

This is my very basic EclipseLink configuration. You should add EclipseLink specific configuration properties to jpaProperties, and provide configuration data to the entity manager factory bean (emf) so that it can instantiate the right provider.

Sometimes I just want to apply to a property exactly the same Bean Validator validations I apply to another property.

Point in case: I have a password property in a User class, and there is a ChangePassword data transfer object somewhere else that happens to have currentPassword, newPassword and repeatPassword fields, used precisely to change User.password.

It is obvious that I will want to apply the validations for User.property to all these fields. And, of course, I want changes to validation rules in the original property to be taken into account, automatically.

Copying them is a no-no, because we will violate the DRY (Don’ Repeat Yourself) rule, and creating a custom validation annotation, say @Password, might be overkill. And it would not convey the right meaning, or that’s how I see it.

Creating some kind of DelegateValidation validator that replicates other validations makes a lot of sense, as it clearly conveys the intention and keeps code DRY.

Here we must get access to the Validator we are using to peform validations to ask it to perform validations against the tracked property. Since I use CDI, as well as the Seam validtor module, I rely on them to inject the right Validator instance in my validator implementation.

However, if you are not using CDI/Seam, or just to make testing easier, I am providing a way to supply a validator via the setGlobalValidator method, that you should call before any validations are performed.

Last but not least, let me tellyou that, if you provide a wrong property name for the validator, the validation will fail with a ValidationException, as attested by some of the following tests.

The tests

For the sake of completeness, here are my tests, written against TestNg: