Friday, August 29, 2014

Spring MVC’s Default Behavior

View Resolver

First up is the view resolver. We can’t specify all the views ahead of time and the only way the marketing department communicates new pages to us is by publishing them into our JSP directory, Springs InternalResourceViewResolver is the perfect fit.
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/content/" />
    <property name="suffix" value=".jsp" />
</bean>
Assuming the build script pulls the published HTML files into the projects /WEB-INF/jsp/content directory and renames them with a “.jsp” extension, then all the pages should be available with a view that matches the path to the page, minus the ViewResolver’s specified prefix and suffix. For example, if we have a page stored at /WEB-INF/jsp/content/members/profile.jsp, A controller can access that page by returning a view name of members/profile.

The Default Controller

Now that there is a view resolver capable of seeing all the pages produced by the marketing department, a controller must be created and mapped so that it will produce the correct view name.
package com.sourceallies.base;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class DefaultController {
 
    @RequestMapping("/**/*")
    public void defaultRequest(){}
}
That was easy. It would be hard to come up with a simpler controller, in fact it doesn’t look like it does anything at all! In reality it is taking advantage of Spring MVC’s default behavior for just about everything. With annotation based controllers, request mapped methods have a variety of possible return types. Strings are interpreted as view names, and ModelView objects are used like they were in previous versions of Spring MVC. But if the method has no return type then we get some interesting behavior. On void methods (or String methods that return null) Spring MVC looks at the request URI, strips off the app context and any file extensions, and uses whatever is left over as the view name. For example, if my application is mapped to /corporate/ and my request URL is /corporate/members/profile.html then Spring MVC will generate a view name of “members/profile”. The other thing to note is the RequestMapping, /**/* is the most generic mapping there is. It will match any request that comes through the Spring MVC servlet. This is how to avoid having to add new mappings for every new page. This is exactly what we want to use when working with the ViewResolver we defined earlier. All of the pages from the CMS live relative to each other, and the URLs requested from the client should match the file structure from the CMS.
So at this point I now have a more complicated version of the normal servlet request process. Its usefulness becomes apparent when marketing needs a new piece of data on a specific page and I need to create a controller.

@Controller
public class ProfileController {
 
    @RequestMapping("/members/profile.html")
    public void testRequest(Model model) {
        Profile profile = ...LookupProfile
 
        model.addAttribute("profile", profile);
    }
}
All I have to do is create a new controller and map it to the page name from the marketing department.

Wednesday, August 20, 2014

Understanding Spring MVC Model and Session Attributes

Spring MVC Scopes
When I started writing Web applications in Spring MVC, I found the Spring model and session attributes to be a bit of a mystery – especially as they relate to the HTTP request and session scopes and their attributes that I knew well.  Was a Spring model element going to be found in my session or request?  If so, how could I control this?  In this post, I hope to demystify how Spring MVC’s model and session work.
Spring’s @ModelAttribute
There are several ways to add data or objects to Spring’s model.  Data or objects are typically added to Spring’s model via an annotated method in the controller.  In the example below, @ModelAttribute is used to add an instance of MyCommandBean to the model under the key of “myRequestObject”.

@Controller
public class MyController {
 
    @ModelAttribute("myRequestObject")
    public MyCommandBean addStuffToRequestScope() {
        System.out.println("Inside of addStuffToRequestScope");
        MyCommandBean bean = new MyCommandBean("Hello World",42);
        return bean;
    }
 
    @RequestMapping("/dosomething")
    public String requestHandlingMethod(Model model, HttpServletRequest request) {
        System.out.println("Inside of dosomething handler method");
 
        System.out.println("--- Model data ---");
        Map modelMap = model.asMap();
        for (Object modelKey : modelMap.keySet()) {
            Object modelValue = modelMap.get(modelKey);
            System.out.println(modelKey + " -- " + modelValue);
        }
 
        System.out.println("=== Request data ===");
        java.util.Enumeration reqEnum = request.getAttributeNames();
        while (reqEnum.hasMoreElements()) {
            String s = reqEnum.nextElement();
            System.out.println(s);
            System.out.println("==" + request.getAttribute(s));
        }
 
        return "nextpage";
    }
 
         //  ... the rest of the controller
}

On an incoming request, any methods annotated with @ModelAttribute are called before any controller handler method (like requestHandlingMethod in the example above).  These methods add data to a java.util.Map that is added to the Spring model before the execution of the handler method.  This can be demonstrated by a simple experiment.  I created two JSP pages:  index.jsp and nextpage.jsp.  A link on index.jsp page is used to send a request into the application triggering the requestHandlingMethod() of MyController.  Per the code above, the requestHandlingMethod() returns “nextpage” as the logical name of the next view which is resolved to nextpage.jsp in this case.

modeldataexample

When this little Web site is executed in this fashion, the System.out.println’s of the controller, show how the @ModelAttribute method is executed before the handler method.  It also shows that the MyCommandBean was created and added to Spring’s model and was available in the handler method.


Inside of addStuffToRequestScope
Inside of dosomething handler method
--- Model data ---
myRequestObject -- MyCommandBean [someString=Hello World, someNumber=42]
=== Request data ===
org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE
==WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 13 21:40:56 CDT 2013]; root of context hierarchy
org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER
==org.springframework.web.servlet.theme.FixedThemeResolver@204af48c
org.springframework.web.servlet.DispatcherServlet.CONTEXT
==WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 13 21:40:56 CDT 2013]; root of context hierarchy
org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping
==dosomething.request
org.springframework.web.servlet.HandlerMapping.bestMatchingPattern
==/dosomething.*
org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER
==org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@18fd23e4

Now, the question is “where is Spring model data stored?”  Is it stored in the standard Java request scope?  The answer is – yes… eventually.  As you can tell from the output above, MyCommandBean is in the model, but not yet in the request object when the handler method executes.  Indeed, Spring does not add the model data to the request as an attribute until after the execution of the handler method and before presentation of the next view (in this case the nextpage.jsp).
modeltorequest
This can also be demonstrated by printing out the attribute data stored in the HttpServletRequest in both index.jsp and nextpage.jsp.  I arranged for both of these pages to use a JSP scriptlet (shown below) to display the HttpServletRequest attributes.

<hr />
<h3>Request Scope (key==values)</h3>
<%
    java.util.Enumeration<String> reqEnum = request.getAttributeNames();
    while (reqEnum.hasMoreElements()) {
        String s = reqEnum.nextElement();
        out.print(s);
        out.println("==" + request.getAttribute(s));
%><br />
<%
    }
%>

When the application comes up and index.jsp is displayed, you can see that there are no attributes in request scope.
Request Attributes Before
In this case, when the “do something” link is clicked it causes the MyController’s handler method to execute, which in turn causes the nextpage.jsp to be displayed.  Given the same JSP scriptlet is on the nextpage.jsp, it too renders what is in the request scope.  Lo and behold, when nextpage.jsp renders, it shows the model MyCommandBean created in the controller has been added to the HttpServletRequest scope!  The Spring model attribute key of “myRequestObject” has even been copied and used as the request attribute’s key.
requestattributesafterSo Spring model data created prior to (or during) the handler method execution has been copied to the HttpServletRequest before the next view is rendered.


Spring’s @SessionAttributes
So now you know how Spring’s model data is managed and how it relates to regular Http request attribute data.  What about Spring’s session data?
Spring’s @SessionAttributes is used on a controller to designate which model attributes should be stored in the session.

In actually, what @SessionAttributes allows you to do is tell Spring which of your model attributes will also be copied to HttpSession before rendering the view.  Again, this can be demonstrated with a little code.

In my index.jsp and nextpage.jsp, I added an additional JSP scriptlet to show the HttpSession attributes.

<h3>Session Scope (key==values)</h3>
<%
  java.util.Enumeration<String> sessEnum = request.getSession()
    .getAttributeNames();
  while (sessEnum.hasMoreElements()) {
    String s = sessEnum.nextElement();
    out.print(s);
    out.println("==" + request.getSession().getAttribute(s));
%><br />
<%
  }
%>

I annotated MyController with @SessionAttributes to put the same model attribute (myRequestObject) in Spring session.

@SessionAttributes("myRequestObject")
public class MyController {
  ...
}
 
I also added code to the handler method of my controller to show what attributes are in HttpSession (just as it shows what attributes are in HttpServletRequest).

@SuppressWarnings("rawtypes")
@RequestMapping("/dosomething")
public String requestHandlingMethod(Model model, HttpServletRequest request, HttpSession session) {
  System.out.println("Inside of dosomething handler method");
 
  System.out.println("--- Model data ---");
  Map modelMap = model.asMap();
  for (Object modelKey : modelMap.keySet()) {
    Object modelValue = modelMap.get(modelKey);
    System.out.println(modelKey + " -- " + modelValue);
  }
 
  System.out.println("=== Request data ===");
  java.util.Enumeration<String> reqEnum = request.getAttributeNames();
  while (reqEnum.hasMoreElements()) {
    String s = reqEnum.nextElement();
    System.out.println(s);
    System.out.println("==" + request.getAttribute(s));
  }
 
  System.out.println("*** Session data ***");
  Enumeration<String> e = session.getAttributeNames();
  while (e.hasMoreElements()){
    String s = e.nextElement();
    System.out.println(s);
    System.out.println("**" + session.getAttribute(s));
  }
 
  return "nextpage";
}

So now, we should be able to see what is in the session object before, during, and after Spring MVC has handled one HTTP request when annotated with @SessionAttributes.  The results are shown below.  First, as the index.jsp page is displayed (before the request is sent and handled by Spring MVC), we see that there is no attribute data in either the HttpServletRequest or HttpSession.

During the execution of the handler method (requestHandlingMethod), you see MyCommandBean has been added to the Spring model attributes, but it is not yet in the HttpServletRequest or HttpSession scope.
During handler method executionBut after the handler method has executed and when the nextpage.jsp is rendered, you can see that the model attribute data (MyCommandBean) has indeed been copied as an attribute (with the same attribute key) to both HttpServletRequest and HttpSession. HttpSession and HttpServletRequest attributes after handler method completes
Controlling Session Attributes
So now you have an appreciation of how Spring model and session attribute data are added to HttpServletRequest and HttpSession. But now you may be concerned with how to manage that data in Spring session. Spring provides a means to remove Spring session attributes, and thereby also remove it from HttpSession (without having to kill the entire HttpSession). Simply add a Spring SessionStatus object as a parameter to a controller handler method. In this method, use the SessionStatus object to end the Spring session.

@RequestMapping("/endsession")
public String nextHandlingMethod2(SessionStatus status){
  status.setComplete();
  return "lastpage";
}

@RequestMapping("/endsession")
public String nextHandlingMethod2(SessionStatus status){
  status.setComplete();
  return "lastpage";
}


Monday, August 18, 2014

Hibernate’s and LazyInitializationExceptions

For many years LazyInitializationExceptions have become most frustrating point of Hibernate. This exception occurs when you try to access an un-initialised lazy association of a detached entity.
Entities become detached in three different ways;
  • session close
  • session clear
  • session evict
You have to be sure that any lazy attributes you will access be initialised before those three cases happen. Otherwise you will come up with the infamous Lazy exception.
So what are the ways to get rid of that Lazy exception? There are several ways available in Hibernate and employed among the community;
  • You can invoke Hibernate.initialize(proxy) on each lazy attribute before their owning entity becomes detached.
  • You have to access their specific properties such as ids before detachment such as x.getLazySet().size() or x.getLazyManyToOneAssoc().getId().
  • For web applications you can also employ OpenSessionInViewFilter which keeps session open until the end of view render process so that entities wont become detached before those lazy attributes accessed.
  • You can also reattach detached entities before accessing their lazy attributes using session merge or lock operations.
With Hibernate 4.1.6 a new feature is introduced to handle those lazy association problems. When you enable hibernate.enable_lazy_load_no_trans property in hibernate.properties or in hibernate.cfg.xml, you will have no LazyInitializationException any more. It works for any sort of lazy associations not only many sided (1:M, N:M) but also one sided (1:1,:M:1) as well.
So what does this property do? It simply signals Hibernate that it should open a new session if session which is set inside current un-initialised proxy is closed. You should be aware that if you have any other open session which is also used to manage current transaction, this newly opened session will be different and it may not participate into the current transaction unless it is JTA. Because of this TX side effect you should be careful against possible side effects in your system.
Another important point is that this feature only works for proxies whose sessions are closed or their owning entity is evicted from the session. If the entity become detached with session clear then you will still have the lazy problem. According to code comments in Hibernate’s AbstractPersistentCollection class, Hibernate team aims to handle session clear in the next major release.

Friday, August 15, 2014

Flushing Hibernate

Flushing Hibernate

Today I am going to write about Hibernate flushing. Do not worry, I am not going to flush Hibernate to the toilet. I will write about the way, how Hibernate propagates changes to the database.
When you are modifying data using Hibernate, you have to keep in mind that Hibernate uses so called write-behind. It means that Hibernate propagates changes to the database as late as possible. By default this propagation (flushing) happens at the following times
  • when transaction is committed
  • before query is executed
  • when flush() method is called explicitly
Usually such behavior is a good thing. It enables Hibernate to optimize data modifications and allows grouping many changes to one big batch update. But sometimes you can encounter some interesting issues. Lets show it on some example. Lets have following entity class:



01 @Entity
02 public class Client  {
03   
04   @Id @GeneratedValue(strategy=GenerationType.AUTO)
05   private Long id;
06
07   @Column(unique=true,nullable=false)
08   private String personalNumber;
09   
10   @Column
11   private String name;
12   
13   .
13   .
13   .
14 }
We see that a client has id which is used internally as an identifier. Moreover a client has a personal number which we are using as a business key. Then he has some other attributes as name. Notice that the personal number is obligatory and it has to be unique.

01     Client client = new Client(PERSONAL_NUM);
02     LOG.debug("Creating first client");
03     clientDao.createClient(client);
04     
05     LOG.debug("Changing first client");
06     client.setName("Carl von Bahnhof");
07     
08     LOG.debug("Deleting first client");
09     clientDao.deleteClient(client.getId());
10     
11     LOG.debug("Trying to load first client");
12     assertNull(clientDao.loadClientWithPersonalNumberOrReturnNull(PERSONAL_NUM));
13     
14     LOG.debug("Creating second client");
15     clientDao.createClient(new Client(PERSONAL_NUM));

When it is executed on HSQLDB we get following output (we see my logging messages mixed with Hibernate SQL output).

Creating first client
insert into Client (name, personalNumber, id) values (?, ?, ?)
call identity()
Changing first client
Deleting first client
Trying to load first client
delete from Client where id=?
select client0_.id as id2_, client0_.name as name2_, client0_.personalNumber as personal3_2_ from Client client0_ where client0_.personalNumber=?
Creating second client
insert into Client (name, personalNumber, id) values (?, ?, ?)
call identity()
We see that inserts are called at once. They are not postponed until flush. In this case, Hibernate has to call insert at once because it has to get the client id from the database. (remember all non-transient entities have to have id) So inserts can not wait until flush, they have to be executed directly. In order to make our example more clear, we can change id generation strategy to sequence.



01 @Entity
02 public class Client  {
03   
04   @Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
05   private Long id;
06
07   @Column(unique=true,nullable=false)
08   private String personalNumber;
09   
10   @Column
11   private String name;
12   
13   .
14   .
15   .
16 }
To get the client id, insert is not needed any more. It can be postponed until flush and we get following output
Creating first client
select next value for hibernate_sequence from dual_hibernate_sequence
Changing first client
Deleting first client
Trying to load first client
insert into Client (name, personalNumber, id) values (?, ?, ?)
delete from Client where id=?
select client0_.id as id2_, client0_.name as name2_, client0_.personalNumber as personal3_2_ from Client client0_ where client0_.personalNumber=?
Creating second client
insert into Client (name, personalNumber, id) values (?, ?, ?)
As you can see creation of the first client and his deletion is realized just before the select statement. Changes have to be propagated to the DB so the select statement has access to changed data. You can notice, that there is no update, change of the name was already included into the insert statement. So far so good. Where is the problem? Lets comment out the query (You do not have to comment it out, in the real world it can be bypassed by the second-level cache).



01     Client client = new Client(PERSONAL_NUM);
02     LOG.debug("Creating first client");
03     clientDao.createClient(client);
04     
05     LOG.debug("Changing first client");
06     client.setName("Carl von Bahnhof");
07     
08     LOG.debug("Deleting first client");
09     clientDao.deleteClient(client.getId());
10     
11     //LOG.debug("Trying to load first client");
12     //assertNull(clientDao.loadClientWithPersonalNumberOrReturnNull(PERSONAL_NUM));
13     
14     LOG.debug("Creating second client");
15     clientDao.createClient(new Client(PERSONAL_NUM));
We get following output
Creating first client
select next value for hibernate_sequence from dual_hibernate_sequence
Changing first client
Deleting first client
Creating second client
insert into Client (name, personalNumber, id) values (?, ?, ?)
insert into Client (name, personalNumber, id) values (?, ?, ?)
SQL Error: 0, SQLState: null
failed batch
Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:438)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:346)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:199)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:340)
at org.springframework.test.context.junit4.SpringMethodRoadie.runAfters(SpringMethodRoadie.java:351)
at org.springframework.test.context.junit4.SpringMethodRoadie.runBeforesThenTestThenAfters(SpringMethodRoadie.java:262)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:234)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:204)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:146)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:151)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.BatchUpdateException: failed batch
at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 31 more
Wow. It looks like Hibernate is trying to insert both clients with the same personal number without deleting the first one. Lets try to remove uniqueness condition from the client and take a look at the output:
Creating first client
select next value for hibernate_sequence from dual_hibernate_sequence
Changing first client
Deleting first client
Creating second client
insert into Client (name, personalNumber, id) values (?, ?, ?)
insert into Client (name, personalNumber, id) values (?, ?, ?)
delete from Client where id=?
Yes, Hibernate changed order of the commands! Without the unique constraint it does not matter, final result is the same. But with the constraint enabled, we can not use our code any more. Is it a bug? No, it is a feature. If you dig deep into the Hibernate source code, you will find following comment
Execute all SQL and second-level cache updates, in a
special order so that foreign-key constraints cannot
be violated:
  1. Inserts, in the order they were performed
  2. Updates
  3. Deletion of collection elements
  4. Insertion of collection elements
  5. Deletes, in the order they were performed
And that is exactly our case. When flushing, Hibernate executes all inserts before delete statements.
So if we need to run our example, we have to force Hibernate to flush the delete before the second insert. The best way is to call entityManager.flush() explicitly just after the delete.
To reiterate, Hibernate is using write-behind. All data manipulating statements are executed as late as possible. One exception are insert statements. Sometimes Hibernate needs to call insert in order to get the ID of the entity. The important point is, that order of the commands can be changed by Hibernate. Usually it does not matter, since transactions are atomic. But sometimes we can encounter interesting issues. Especially when using database constraints.

Tuesday, August 12, 2014

JPA basic example with EntityManager


JPA basic example with EntityManager , Spring and Maven
Our pom.xml will be like this..
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hopcroft.examples.spring</groupId>
    <artifactId>simpledao</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <pluginRepositories>
        <pluginRepository>
            <id>maven-annotation</id>
            <url>http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo</url>
        </pluginRepository>

    </pluginRepositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                    </compilerArguments>
                </configuration>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <groupId>org.bsc.maven</groupId>
                <artifactId>maven-processor-plugin</artifactId>
                <version>2.0.2</version>
                <executions>
                    <execution>
                        <id>process</id>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <phase>generate-sources</phase>
                        <configuration>
                            <outputDirectory>src/main/generated-java</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>src/main/generated-java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>ejb3-persistence</artifactId>
            <version>1.0.2.GA</version>
            <type>pom</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.0.0.RELEASE</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.security</groupId>
            <artifactId>jacc</artifactId>
            <version>1.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.10</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.0.5.RELEASE</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.5.0-Final</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-annotations</artifactId>
            <version>3.5.0-Final</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.codehaus.openxma</groupId>
            <artifactId>dsl-platform</artifactId>
            <version>3.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>1.0.0.Final</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>



Our application will have the next structure

 


We have a domain model layer where there is a Car entity that mirrors the database table.
 
Our car entity:
package com.hopcroft.examples.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "Car")
public class Car {
    @Id
    @Column(name = "id")
    private long id;
    @Column(name = "company")
    private String company;
    @Column(name = "model")
    private String model;
    @Column(name = "price")
    private long price;

    public void setId(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public long getPrice() {
        return price;
    }

    public void setPrice(long price) {
        this.price = price;
    }

}
We have also a data access layer where there is a interface called CarDao that defines the methods that we use to interact with our database. This interface will be implemented by the CarDaoImpl.
In some of the later projects we have use a HibernateTemplate object to get the data from our database. Instead of that we are going to use an EntityManager instance. An EntityManager will be a instance of an EntityManagerFactory within JPA. This type of factory means the configuration used to access to our database.
To use JPA in our project we are going to create a persistence unit in the META-INF/persistence.xml file. Within this file we will have a specified persistence unit. What we should do is choosing the transaction type. We need to use the provider that will implement JPA. In our case, we are going to use Hibernate.



<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"

    version="1.0">
    <persistence-unit name="JpaPersistenceUnit"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
    </persistence-unit>
</persistence>

We need to configure our application context in the same way we did when we used an Hibernate sessionFactory. That means, we have to add a dataSource within our context file where we define our url , user, password and the database we are going to use. We define an entityManagerFactory to which we pass the newly created dataSource. This entityManagerFactory object will be controlled by a transactionManager. As we are using JPA we need a org.springframework.orm.jpa.JpaTransactionManager.
There is also a component-scan element. We will explain it when we see our Dao.
Our context file is as follows:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/tx


http://www.springframework.org/schema/tx/spring-tx-3.0.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost/test"
        p:username="root" p:password="" p:initialSize="5" p:maxActive="10">
    </bean>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="entityManagerFactory">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <context:component-scan base-package="com.hopcroft.examples.dao">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Repository" />
    </context:component-scan>

    <bean class="org.springframework.orm.jpa.JpaTransactionManager"
        id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <tx:annotation-driven mode="aspectj"
        transaction-manager="transactionManager" />

    <context:spring-configured />
    <context:annotation-config />
</beans>

After take a look to our configuration files we need to explain our Dao (interface and its implementation).
package com.hopcroft.examples.dao;

import java.util.List;

import org.springframework.dao.DataAccessException;

import com.hopcroft.examples.domain.Car;

public interface CarDao {
    public List<Car> getCars() throws DataAccessException;
    public Car getCar(Long carId) throws DataAccessException;
}

package com.hopcroft.examples.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.hopcroft.examples.domain.Car;

@Repository
public class CarDaoImpl implements CarDao {

    protected EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }
    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Transactional
    public List<Car> getCars() throws DataAccessException {
        Query query = getEntityManager().createQuery("select c from Car c");
        List<Car> resultList = query.getResultList();
        return resultList;
    }
    @Transactional
    public Car getCar(Long carId) throws DataAccessException {
        return getEntityManager().find(Car.class, carId);
    }
}

There is no much to say about the carDao interface. Two methods that we implement within the CarDaoImpl class. We need to explain a couple of things.
First of all we notice that CarDaoImpl is annotated as @Repository. This is an annotation we use to say to the Spring context that our CarDaoImpl is included within its context as a component. Besides the @Repository annotation there are a @Service annotation and a @Controller one. Every annotation extends to the @Component annotation. There is a meaning difference among them, @Repository will indicate our Spring context that we want to add a Dao bean, @Controller a controller and @Service … easy to guess. Do you remenber thecomponent-scan element within our testApplicationContext file?, in this file we tell Spring we are going to incluide as beans every single class with the @Repository annotation, in our case, CarDaoImpl car.
The second annotation we notice is @PersistenceContext. It is in the EntityManager setter method. We get an EntiyManagerFactory object we need for address our database.
We can notice that our methods are annontated as transactional. That means our methods belong to a unique transaction that will be management by the transactionManager we explained in our context file.
Our method logic is quite straightforward. We have a couple of methods, the first one list every car we have stored in our database and the second one use an id to find a specified car. To that we have to use an entityManager. As with HibernateTemplate, our entityManager class will have some basic methods like persist, refresh ó remove. Once our application is created we are going to make a test class.

package com.hopcroft.examples.test;

import java.util.List;
import java.util.logging.Logger;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.hopcroft.examples.dao.CarDao;
import com.hopcroft.examples.domain.Car;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/testApplicationContext.xml" })
public class CarTest {

    @Autowired
    private CarDao carDao;
    private Logger logger = Logger.getLogger("myLog");
    private Long id;

    @Before
    public void init() {
//      carNumber = carDao.getCars().size();
        id = 1L;
    }

    @Test
    public void listCarsTest() {
        List<Car> cars = carDao.getCars();
//      logger.info("Cars: " + cars.size());
        Assert.assertNotNull(cars);
        Assert.assertEquals(15, cars.size());
    }

    @Test
    public void getCarTest() {
        Car car = carDao.getCar(id);
        Assert.assertEquals(id.longValue(), car.getId());
        Assert.assertEquals("Boxster", car.getModel());
    }
}

We annotate our class as always, pointing that we are going to use JUnit4 and the context file we have already created. We are going to get our CarDao from the Spring context. We have some method that we are going to test from a Maven test configuration within STS.