Four lessons learned..

See my new Blog post on the Zalando Tech-Blog.

All the best,

Malte

 

HowTo use Spring Data JPA with Errai

What?

Hi there,

since I had quite a hard time, to integrate Spring Data JPA into an Errai Application, I’d like to share my findings and of course the result.

In general these results can be mapped to any other JEE-App.

Hopefully, this will help someone sometime.

Why do that?

In general, I prefeer to use Spring for many reasons. The first one is, as I started developing my former colleague introduced me into a project where the Spring Framework was used. Before that, I only used Java SE and wasn’t familiar with such kind of technology at all.

After I moved to another company, JEE was more used there than Spring.  Nevertheless, JEE didn’t convince me. I was so happy with all the options Spring gave me:

  • Easy integration tests, by just powering up the needed components
  • Removal of boilerplate code
  • Easy usage of dependency Injection
  • No need for an Application Container
  • And so on…

I nevertheless wanted to have a look in the „plain JEE“ stuff, therefore I started to experiment with the Errai Framework, but I still wanted to use Spring Data JPA because it gives me the option to easily switch my Datasource and to run some tests.

How to do that?

By default, Spring Data offers the option to use it with CDI natively, at the point of time I wanted to make use of it, the documentation of Spring, was barely usable, but there has been opened a JIRA-Ticket for that.

Furthermore I’ve started a discussion in the JBoss Forum, but didn’t receive any answer in that point of time. So I investigated further on my own.

What you need!

You need the following libraries which can be found on mavencentral:

  • Spring-Data-Jpa
  • Spring-Core
  • Spring-Context
  • Spring-Aspects
  • Hibernate

A detailed listing can be found in the repository on github.

In the following I will skip the details about the Errai framework, like how to provide an Endpoint and how to call a service on the server side from client. Nevertheless the code examples can also be seen on github.

Let’s start!

We wan’t to provide the functionality that Users can register for our App. Therefore we have to Implement a POJO named User. A User can have some common values, like an Email-Adress, a username, a password and so on.

@Entity @Portable @Bindable @Table(uniqueConstraints=@UniqueConstraint(columnNames="email")) public class User implements Serializable { @Version private Integer version; @Id @GeneratedValue private Integer id; @NotNull private String email; @NotNull private String firstName; @NotNull private String name; @NotNull private String userName; @NotNull private String password;

In order to enable access to the Database we furthermore have to create a DAO, which needs to extend the interface JPA-Repository:

public interface UserRepository extends JpaRepository { @Query("Select u from User u where u.email = ?1") public User findUserByEmail(String email); }

So far, nothing new, at least if you are known to Spring. The cool thing is, that you have now the full functionality of a basic repository. Like persisting, removing and searching.

But since we want to use the Email-Adress of an user as the primary key, we have to expose a function which can search for the E-mail of an user.

In order to make the Entitymanager, which will be created by Spring, known to the rest of the application context, you have to expose it.

Therefore we have to create a new Class:

public class EntityManagerProducer { @PersistenceContext(name = "persistenceUnit", type= PersistenceContextType.EXTENDED) EntityManager em; @Produces public EntityManager createEntityManager() { return em; } public EntityManager getEm() { return em; } public void setEm(EntityManager em) { this.em = em; } }

That’s it… The last important note is, that you have to set the EntityManager in the context type, extended.  Like this you can use the @Transactional annotation, provided by Spring.

On the serverside we just have to inject the dao, and call the persist method at the wanted location.

@Service @Stateless public class UserEndpoint implements UserService{ @Inject UserRepository userDao; @Transactional @Override public boolean registerNewUser(User user) { if (user == null) { throw new IllegalArgumentException("Something went wrong"); } if (user.getEmail().isEmpty()) { throw new IllegalArgumentException("Email is not set…"); } User existingUser = userDao.findUserByEmail(user.getEmail()); if (existingUser != null) { return false; } else { try{ user = (User) userDao.saveAndFlush(user); }catch(Exception e){ return false; } return user == null ? false : true; } } }

That’s it!

Best Regards,

Malte

 

About me

Hi,

My name is Malte, I am the owner of this Blog.

I studied computer science and am a java developer in Dortmund.

About the blog

I will share information about my experiences as backend developer where I focussed on Java on this blog. I have most experience with the Spring Framework. Furthermore I started using Apache Cassandra around a year ago where I am learning new things every day.

On the other hand I’d like to share some insights about fishing, where I specialised on non-predatory fishes. I started with feeder fishing and currently trying bolognese fishing.

Most of the times I’ll try to write my posts in english.

 

Run Errai/GWT with Gradle

Hi there,

In the last days I tried to get an App with the Errai Framework running. The hard part was, to get it running with Gradle support instead of Maven.

Therefore I decided to create a small howto, to get other people also able to run Errai with Gradle.

At first I’d like to thank Max Barkley, member of the JBoss Team, who gave me the last important hints. And Peter, a co-worker in my Company who helped me to fix the Gradle script.

Prerequisites

To get the App running, you will need:

  • Gradle 1.7, I think it will also work with earlier Versions, but I did it with 1.7
  • Enterprise Application Server

Furthermore you will need the following Dependencies in your Project:

  • org.jboss.errai:errai-javaee-all:2.4.0.Final, which is the current Version the Errai-Framework (28.09.2013)
  • com.google.gwt:gwt-dev:2.5.1, which contains the GWT compiler

You can find the Source Code here.

Lets get it running

I started with searching for a compile script for GWT, because Errai basically just extends GWT, and found a Skript where I had to do some minor modifications.

task compileGwt (dependsOn: classes, type: JavaExec) { 
buildDir = "${project.buildDir}/gwt"
extraDir = "${project.buildDir}/extra" inputs.source sourceSets.main.java.srcDirs 
inputs.dir sourceSets.main.output.resourcesDir
outputs.dir buildDir // Workaround for incremental build (GRADLE-1483)
outputs.upToDateSpec = new org.gradle.api.specs.AndSpec() doFirst { 
 file(buildDir).mkdirs()
} 
main = 'com.google.gwt.dev.Compiler' classpath { [ 
 sourceSets.main.java.srcDirs, // Java source 
 sourceSets.main.output.resourcesDir, // Generated 
 resources sourceSets.main.output.classesDir, // Generated 
 classes sourceSets.main.compileClasspath, // Deps ]
} 
args = [ 'de.coderebell.tts.app', // Your GWT module 
 '-war', buildDir, '-logLevel', 'INFO', '-localWorkers', 
 '2', '-compileReport', '-extra', extraDir ]
 maxHeapSize = '256M' 
}

Furthermore we have to add a few lines for the war plugin, so that it recognizes that there are new Folders:
war.dependsOn compileGwt war { from "$buildDir/gwt" from "$buildDir/extra" }.
Thats it, with running the Task compileGWT gradle will compile all needed files.

To let the app run you just have to deploy it on your Application Server. You also can use the Eclipse GWT plugin. You just have to use the „Run on external Server“ dialogue. This will generate you some unwanted Files in your webapp folder, which you have to clean up afterwards manually.

Known Issues

I wasn’t able to get the App running with Errai version 2.3.2.Final. The app directly crashed during startup. So I decided to use version 2.4.0.Final, after that the AS, I used JBoss 7, threw an exception which you basically can ignore:

Available types: [jarfile, jarUrl, directory, vfsfile, vfszip, org.jboss.errai.common.metadata.WarUrlType@1e8608b4, *.jnilib, *.zip, *.pom] Do you need to add app server specific support to your deployment? (For example, errai-jboss-as-support for AS7) at org.jboss.errai.reflections.vfs.Vfs.fromURL(Vfs.java:126) [reflections-2.4.0.Final.jar:2.4.0.Final]

The JBoss Team is already aware of that.

Cheers,

Malte