days
-1
-2
hours
-1
-2
minutes
-3
-2
seconds
-3
-8
search
Booster #2: DeltaSpike Data

Top 3 JPA productivity boosters for Java EE developers – DeltaSpike Data

Matti Tahvonen
Booster image via Shutterstock

Matti Tahvonen shows us around the lesser-known DeltaSpike Data, number two in the top three ways to enhance your JPA productivity.

In the first part of this article series we discussed how the popular Spring Data library can be easily fitted into otherwise standard Java EE environment. Spring Data automatically generates the most commonly used DAO methods and you can really easily extend it with custom queries, in simple cases without writing any JPQL queries or touching JPA APIs at all.

DeltaSpike Data implements Spring Data like semi-automatically generated data repositories in plain CDI containers. Although it isn’t as mature and as widely used as Spring Data, the largest differences between those seems to be in the amount of quality tutorials and examples. Some things don’t yet feel as fluent as with Spring Data, which might of course be just due to my existing Spring Data experience, but DeltaSpike also has some unique handy features that I’d like to see in Spring Data as well.

A similar ContactRepository to the one we introduced in previous article for SpringData, with one query implemented with naming convention, would look like this:

   @Repository(forEntity = Contact.class)
   public interface ContactRepository extends EntityRepository<Contact, Long> {
       public List<Contact> findByCompany(Company company);
    }

DeltaSpike Data is designed to work using plain CDI container. As we are targeting a modern Java EE environment, we’ll leverage container managed persistence context and JTA transactions. Like with Spring Data, an easy and safe way to do this is a stateless EJB in front of the auto-generated repository class. Similarly to Spring Data, we need to publish EntityManager for CDI managed beans and we need to instruct how it should tackle transactions.

Check out the example project using DeltaSpike Data

Publishing EntityManager for CDI beans works exactly like with Spring Data. In our example application the same CdiConfig class actually publishes it to both libraries. To instruct DeltaSpike Data to avoid calling JPAs low level transaction management APIs, add the following configuration to src/main/resources/META-INF/apache-deltaspike.properties

globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=
org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy

After the setup, you are ready to create similar EJB as with SpringData. The implementation is almost identical, only the delete method changes to remove, but you can hide that fact at the DAO level if you are still uncertain which library to use or switching from one to another. 

   @Stateless
   public class ContactFacade {
       @Inject
       ContactRepository repository;
       public Contact save(Contact entity) {
           return repository.save(entity);
       }
       public void delete(Contact entity) {
           repository.remove(entity);
           //repository.delete(entity);
       }
       public List<Contact> findAll() {
           return repository.findAll();
        }

Differences to Spring Data

If you have some experience with Spring Data, you’ll notice some differences in more advanced usage. The first one you’ll notice when binding a larger table to UI and you need to do paged queries to your database. In Spring Data this is typically done by passing Pageable argument that contains details about sorting and what kind of subset of the results should be returned.

With DeltaSpike data you can add the start index and the maximum amount of results as parameters and annotate them with @FirstResult and @MaxResults. The same can be also achieved by declaring your query methods return type to QueryResult instead of basic List. The QueryResult is an intermediate result, where the query is not yet actually executed, but for which you can define details like sorting and how to limit the result set. A bit different kind of concept than Pageable in Spring, but pretty much same things are possible. I personally have no opinion on which one is better.

In some cases Spring Data still feels bit smarter when it comes to automatic queries based on the naming convention. For example I couldn’t get a function countByInvoicerAndNameLike to work, although it works well in Spring Data. This can though be worked around by writing it as findBy style query and using QueryResult as return type. The count method in your DAO could then look like this:

    public long countContacts(Invoicer invoicer, String filter) {
        return repository.findByInvoicerAndNameLike(invoicer, filter.toUpperCase() + "%")
		.count();
    }

Another tricky part I faced was when creating a case insensitive LIKE query, something you pretty much always want for your search UIs. With Spring Data you can simply append “IgnoreCase” to your method name and all string properties will be handled as you’d expect. When writing this article I created an issue about this to DeltaSpike’s Jira and the DeltaSpike proved to be a really active OS project: the feature was in git repository only a couple of days later. Since 1.3.0 you can use the same IgnoreCase keyword with DeltaSpike Data.

Query by example, an ORM independent solution

Most ORM implementations have proprietary APIs for “query by example” style programming. Many developers have though ignored them lately when trying to work with plain JPA API.

DeltaSpike Data contains a nice implementation independent query by example style API which it provides automatically for all generated repository classes. There is also LIKE query version with nice defaults: ‘%’ chars are appended automatically to strings and case is ignored. Writing the above filtering use case with this api would look like this:

    public List<Contact> findPaged(Company company, String filter, int first, int max) {
        Contact contact = new Contact();
        contact.setCompany(company);
        contact.setName(filter);
        return repository.findByLike(contact, firstResult, maxResults,
                Contact_.invoicer, Contact_.name);
    }

The query by example style queries might increase your LoC a bit but, there readability is awesome for object oriented developer mindset.

DeltaSpike Data also provides a DSL-like API to create JPA 2 Criteria queries. This is a nice improvement to basic JPA criteria API, but I’ll skip discussing about that more in detail. The reason is I haven’t figured out why I’d use that instead of the programmatic queries provided by QueryDSL, which I’ll discuss more in last part of the article series.

See also: JPA productivity booster #1: Spring Data

Author
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies.

Leave a Reply

Be the First to Comment!

avatar
400
  Subscribe  
Notify of