Spring Data JPA Tutorial Part Nine: Conclusions

This is the ninth and the last part of my Spring Data JPA tutorial. Now it is time to take a look of what we have learned, and how we should use it to build better software.

Table of Contents

The contents of my Spring Data JPA tutorial is given in following:

The next step is to take a look of the advantages provided by Spring Data JPA and learn how we can use it in effective manner.

Promises Kept

The goal of the Spring Data JPA project is stated:

Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that's actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.

This is a lot to promise. The question is, has Spring Data JPA achieved its goal. As you have learned from my tutorial, Spring Data JPA has following advantages over the "old school" method of building JPA repositories:

  • It provides CRUD capabilities to any domain object without the need of any boilerplate code.
  • It minimizes the amount of source code needed to write custom queries.
  • It offers simple abstractions for performing common tasks like sorting an pagination.

The thing is that implementing these functions have forced the developers to write a lot of boilerplate code in the past. Spring Data JPA changes all this. It minimizes the amount of code needed for implementing repositories.

Making It Work for You

I hate the term best practices because it has a negative effect on continuous improvement. However, I still feel that it is my responsibility to give you some guidance concerning the usage of Spring Data JPA. Here are my five cents about this matter:

Creating Queries

Your goal should be to use the Spring Data JPA to reduce the amount of code you have to write. With this goal in mind, I will you give some guidelines for creating queries with Spring Data JPA:

  • If the query can be build by using the query generation from method name strategy, I think you should use it. However, if the method name will become long and messy, I would consider using the @Query annotation in order to make the source code more readable.
  • Your second option for creating queries should be the @Query annotation and JPQL. This approach ensures that the you will not have to write more code than it is necessary.
  • Use JPA Criteria API or Querydsl only when you have no other options. Remember to extract the query generation logic into separate classes which creates Specification or Predicate objects (Depending on your technology selection).

JPA Criteria API Versus Querydsl

This is a question which should be asked by each developer. The usage of JPA Criteria API has been argued by claiming that you can use it to build type safe queries. Even though this is true, you can achieve the same goal by using the Querydsl. The first round ends in a draw, and we need to look for the answer from a bit deeper.

I will compare these two options in following categories: readability and testability.

Readability

Programs must be written for people to read, and only incidentally for machines to execute

- Abelson and Sussman on Programming.

With this guideline in mind, lets take a look of the implementations, which I created for my previous blog entries. The requirements of the search function are following:

  • It must be possible to search persons by using their last name as a search criteria.
  • The search function must return only such persons whose last name begins with the given search term.
  • The search must be case insensitive.

First, lets take a look of the implementation which is using the JPA Criteria API. The source code of my static meta model is given in following:

@StaticMetamodel(Person.class)
public class Person_ {
    public static volatile SingularAttribute<Person, String> lastName;
}

The source code of my specification builder class is given in following:

public class PersonSpecifications {

    /**
     * Creates a specification used to find persons whose last name begins with
     * the given search term. This search is case insensitive.
     * @param searchTerm
     * @return
     */
    public static Specification<Person> lastNameIsLike(final String searchTerm) {
        
        return new Specification<Person>() {
            @Override
            public Predicate toPredicate(Root<Person> personRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {
                String likePattern = getLikePattern(searchTerm);                
                return cb.like(cb.lower(personRoot.<String>get(Person_.lastName)), likePattern);
            }
            
            private String getLikePattern(final String searchTerm) {
                StringBuilder pattern = new StringBuilder();
                pattern.append(searchTerm.toLowerCase());
                pattern.append("%");
                return pattern.toString();
            }
        };
    }
}

Second, the source code of the implementations which uses Querydsl is given in following:

public class PersonPredicates {

    public static Predicate lastNameIsLike(final String searchTerm) {
        QPerson person = QPerson.person;
        return person.lastName.startsWithIgnoreCase(searchTerm);
    }
}

This use case is pretty simple but it can still be used for demonstrating the differences of the JPA Criteria API and the Querydsl. The source code written by using Querydsl is clearly more readable than the one using the JPA Criteria API. Also, when the queries become more complex, the difference will be much bigger.

I would say that this round goes to Querydsl.

Testability

Software testability is the degree to which a software artifact (i.e. a software system, software module, requirements or design document) supports testing in a given context.

- Wikipedia.

In other words, the testability of your code defines the amount and quality of tests you can write at the same cost. If the testability of your code is high, you can write more tests with better quality than in a situation where the testability of your code is low.

Lets keep this measurement in mind when we will compare the unit tests written for implementations which were presented earlier.

First, lets check out the unit test for the implementation which uses the JPA Criteria API:

public class PersonSpecificationsTest {
    
    private static final String SEARCH_TERM = "Foo";
    private static final String SEARCH_TERM_LIKE_PATTERN = "foo%";
    
    private CriteriaBuilder criteriaBuilderMock;
    
    private CriteriaQuery criteriaQueryMock;
    
    private Root<Person> personRootMock;

    @Before
    public void setUp() {
        criteriaBuilderMock = mock(CriteriaBuilder.class);
        criteriaQueryMock = mock(CriteriaQuery.class);
        personRootMock = mock(Root.class);
    }

    @Test
    public void lastNameIsLike() {
        Path lastNamePathMock = mock(Path.class);        
        when(personRootMock.get(Person_.lastName)).thenReturn(lastNamePathMock);
        
        Expression lastNameToLowerExpressionMock = mock(Expression.class);
        when(criteriaBuilderMock.lower(lastNamePathMock)).thenReturn(lastNameToLowerExpressionMock);
        
        Predicate lastNameIsLikePredicateMock = mock(Predicate.class);
        when(criteriaBuilderMock.like(lastNameToLowerExpressionMock, SEARCH_TERM_LIKE_PATTERN)).thenReturn(lastNameIsLikePredicateMock);

        Specification<Person> actual = PersonSpecifications.lastNameIsLike(SEARCH_TERM);
        Predicate actualPredicate = actual.toPredicate(personRootMock, criteriaQueryMock, criteriaBuilderMock);
        
        verify(personRootMock, times(1)).get(Person_.lastName);
        verifyNoMoreInteractions(personRootMock);
        
        verify(criteriaBuilderMock, times(1)).lower(lastNamePathMock);
        verify(criteriaBuilderMock, times(1)).like(lastNameToLowerExpressionMock, SEARCH_TERM_LIKE_PATTERN);
        verifyNoMoreInteractions(criteriaBuilderMock);

        verifyZeroInteractions(criteriaQueryMock, lastNamePathMock, lastNameIsLikePredicateMock);

        assertEquals(lastNameIsLikePredicateMock, actualPredicate);
    }
}

Second, the unit test for the implementation using Querydsl is given in following:

public class PersonPredicatesTest {
    
    private static final String SEARCH_TERM = "Foo";
    private static final String EXPECTED_PREDICATE_STRING = "startsWithIgnoreCase(person.lastName,Foo)";

    @Test
    public void lastNameLike() {
        Predicate predicate = PersonPredicates.lastNameIsLike(SEARCH_TERM);
        String predicateAsString = predicate.toString();
        assertEquals(EXPECTED_PREDICATE_STRING, predicateAsString);
    }
}

After seeing the unit tests for both implementations, it should be obvious that writing unit tests for Querydsl is much easier than writing unit tests for the JPA Criteria API. Also, the unit test written to test the Querydsl predicate builder is much easier to understand. This is valuable because unit tests should also be used to document the behavior of the system.

At this point it should be clear that the winner of this round is Querydsl

PS. I am aware that unit tests do no ensure that the results returned by the created query are correct. However, I believe that they are still valuable because running unit tests is typically dramatically faster than running integration tests. It is still good to understand that in the context of integration testing, the testability of both implementations is equal.

Conclusions

The question is:

Should I use the JPA Criteria API or Querydsl?

It depends. If you are starting from scratch and you have a total control over your technology selections, you should at least consider using Querydsl. It makes your code easier to write and read. It also means that writing unit tests for your code is simpler and faster.

On the other hand, if you are modifying an existing system to use Spring Data JPA, and the existing code is using the JPA Criteria API, you might want to continue using it for the sake of consistency.

The fact is that there is no right answer for this question. The answer depends always from external requirements. The only thing you can do, is to ensure that you are aware of the different options, which are available to you. Only then you can choose the right tool for the task in hand.

There is Still More to Learn

The truth is that I have only scratched the surface of implementing JPA based repositories. I hope that the recommendations given in this blog entry will help you to take the first step, but I have to admit that there is a lot more to learn. I hope that the following resources will help you in your journey:

Reference Documentation

JPA Criteria API 2.0

Querydsl

If you want to learn how to use Spring Data JPA, you should read my Spring Data JPA tutorial.
42 comments… add one
  • Antti K May 10, 2012 @ 16:58

    This has been awesome stuff. Thanks for sharing. Especially the github projects are really valuable.

    • Petri May 10, 2012 @ 18:19

      Antti,

      Thanks for the feedback. It is great to hear that you have find this tutorial useful.

  • Timo Westkämper Jun 19, 2012 @ 22:54

    Nice blog post again. One other benefit of Querydsl compared to the JPA 2 Criteria API in the Spring Data context is that it is also available for some other backends, at the moment MongoDB and JDBC.

    • Petri Jun 20, 2012 @ 21:42

      Timo,

      thanks for your comment. The support for MongoDB and JDBC is indeed a strong benefit of Querydsl. However, I feel that there might be some work to be done in order improve the general awareness about Querydsl.

      • Raj Nov 5, 2020 @ 11:48

        does querydsl support postgres

        • Petri Nov 5, 2020 @ 16:39

          Yes. However, nowadays I am using jOOQ because it has a better API (in my opinion).

  • Guido Medina Nov 1, 2012 @ 13:47

    After some days googling I couldn't find a better Spring JPA tutorial than this one, Spring data team should hire you to write some documentation and working examples for them, I read their Spring JPA doc and it is vague compared to this one, very well done.

    • Petri Nov 1, 2012 @ 14:17

      Guido,

      Thanks for your comment. I am happy to hear that you found this tutorial useful.

      Some parts of this tutorial contain a bit outdated information since the tutorial is based on 1.0.2 version of Spring Data JPA. However, I have written a book called Spring Data Standard Guide that is an extended edition of this tutorial. This book covers the usage of Spring Data JPA 1.2.0 and Spring Data Redis 1.0.1.

  • Guido Medina Nov 1, 2012 @ 16:09

    Very nice, I'll get the book ASAP, I was about to ask questions but a book should answer most, I have though one question of a matter of opinion, JPA reporsitories are nice, but what if you need to build your query base on optional parameters?

    Let's say, you have a table of events, and you want a list of events between a time frame (findByTimeBetween signature)? Answering the question myself, it seems to me that the best builder pattern like usable for this is the Criteria API (Passing a null to a Between signature method raises an exception), which I like it more soft than hard typed (metamodel), any thoughts on this? Or, does the book cover stuff like that?

    • Petri Nov 1, 2012 @ 16:32

      Hi Guido,

      You have two options (you already figured the first one out):

      • You can use the JPA Criteria API as explained in the fourth part of this tutorial. This approach is perfectly viable but it has two problems: 1) the criteria API is not very easy to use, especially if the created query is complex and 2) The code that uses the criteria API is not very readable.
      • You can Querydsl and follow the approach described in the fifth part of this tutorial. I would recommend using this approach since the Querydsl API is a lot cleaner and easier to use than the JPA Criteria API. However, this approach has two downsides: 1) The Querydsl query types are created by using Maven APT plugin and 2) The Eclipse integration of Querydsl is not working (at least this was the situation a few months ago).

      The book covers both of these situations. Also, the book has 11 different implementations of a simple contact manager application that use Spring Data JPA. 7 of those applications demonstrate the different query creation techniques (1 technique per application) and 4 demonstrate other concepts. These applications makes it easy to start experimenting right away (it can be frustrating to start building application from scratch if you are not sure how things work).

      Also, if you have more questions, I will be happy to answer them.

  • Guido Medina Nov 12, 2012 @ 19:14

    Hi Petri, I just overview the whole book, it is very nice, I do feel it is missing one or two chapters with some corner cases scenario, not that I wanted one specific scenario in it, but it would help to shed some light/ideas.

    There is still the scenario that I described to you before about dynamic queries with JPA 2 Criteria API, our project is kind of overloaded already and for the use cases we have I don't think we are going to into any specific complex scenario, for such cases I would just use standard JPQL queries.

    To complete my puzzle I need just one idea, I don't want to go thru the hassle of creating my own custom Pageable by using .count(...), so I was thinking if there is a way to link Criteria API with Spring Pageable interface or PageRequest class.

    I know, in the worst scenario I will just create a Generic method where I pass a Predicate, a Sort and a Page request to manually execute two queries (one to count and another which will actually do the job) base on the passed Predicate.

    Here is a working example, but it is missing the link between Pageble and Criteria, we use this with JPA interceptor (new code in progress) which has every object backed by Riak (Think of it Redis like with consistency and availability in our case, fast KV):

    @Repository
    public class UpdateChunkServiceImpl implements UpdateChunkService
    {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<UpdateChunk> findByChunkTypeAndTimeBetween(final UpdateChunkType chunkType, final DateTime fromDate, final DateTime toDate, int pageIndex)
    {
    final CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
    CriteriaQuery<UpdateChunk> criteriaQuery=criteriaBuilder.createQuery(UpdateChunk.class);

    final Root<UpdateChunk> root=criteriaQuery.from(UpdateChunk.class);
    final Path<DateTime> timePath=root.get("time");
    final Path<Integer> chunkTypePath=root.get("chunkType");
    Predicate predicate=null;

    if(chunkType != null){
    predicate=addAndPredicate(criteriaBuilder, predicate, criteriaBuilder.and(criteriaBuilder.equal(chunkTypePath, chunkType.getTypeId())));
    }
    if(fromDate != null){
    predicate=addAndPredicate(criteriaBuilder, predicate, criteriaBuilder.and(criteriaBuilder.greaterThanOrEqualTo(timePath, fromDate)));
    }
    if(toDate != null){
    predicate=addAndPredicate(criteriaBuilder, predicate, criteriaBuilder.and(criteriaBuilder.lessThanOrEqualTo(timePath, toDate)));
    }
    if(predicate != null){
    criteriaQuery=criteriaQuery.where(predicate);
    }
    criteriaQuery=criteriaQuery.orderBy(criteriaBuilder.desc(timePath));
    return entityManager.createQuery(criteriaQuery).getResultList();
    }

    private Predicate addAndPredicate(final CriteriaBuilder criteriaBuilder, final Predicate oldPredicate, final Predicate newPredicate)
    {
    return oldPredicate != null ? criteriaBuilder.and(oldPredicate, newPredicate) : newPredicate;
    }

    }

    • Petri Nov 12, 2012 @ 20:03

      Thanks for taking a look at my book! I agree that it lacks "advanced" concepts but I was under a strict page count limit given by the publisher which made it practically impossible to add these concepts to the book. We were originally planning to add a chapter about Spring Data Hadoop as well but the page count limit made it impossible. I ended up publishing that chapter in my blog.

      About your problem: Are you trying to figure out a way to implement this piece code with Spring Data JPA or just use parts of it in your implementation?

      If you want to use Spring Data JPA, you have to follow the steps described in the seventh part of my Spring Data JPA tutorial.

      If you want to use only parts of it and build your own pagination logic, you could find some answers from the source code of the SimpleJpaRepository class. Check the private readPage(TypedQuery<T> query, Pageable pageable, Specification<T> spec) method that is used to read the objects belonging to the requested page from the database.

      • Guido Medina Nov 12, 2012 @ 22:10

        My plans are to use strictly Spring Data JPA wired with Hibernate 3.6.10.Final because version 4 has no support yet for Joda time and few other things, using Spring data repositories for the simple scenarios and Criteria API for more complex scenarios, then by using Hibernate interceptor manage the backed Riak data, think of it as a JPA hybrid JPA where you can do SQL for filtering and KV for fetching, of course, storing data will still do its part in SQL for very few fields, like ID, time, some categories, but the raw data will only be stored in NoSQL, we want to follow a simple standard like the combination of Spring Data + JPA 2, simplicity of proxying injection and at the same time the complexity of our other layer (NoSQL)

        So are objects have Jackson annotations AND JPA annotations which with the aid of Hibernate interceptors will do both with the same @Persistent @Json instance.

        • Petri Nov 12, 2012 @ 22:39

          So basically you want to:

          1. Get the ids belonging to the request page from a relational database by using the Criteria API?
          2. Use the Hibernate interceptor to get the raw data from Riak by using the obtained ids?

          Is there some reason why you prefer using Hibernate interceptors instead of simply getting the raw data from Riak after you have received the ids?

          I have not personally used Hibernate interceptors so I am kind of shooting blind here. However, I took a quick look of the Javadoc and you might be able to use them if you:

          1. Annotate the fields that are not persisted to relational database with the @Transient annotation.
          2. Treat the UpdateChunk class as a "normal" entity, and build the query executed against the relational database by following the approach described in my Spring Data JPA tutorial that talks about pagination.
          3. Use the interceptor to populate the transient fields with the data fetched from Riak

          This is getting interesting. I definitely want to know if this works.

          • Guido Medina Nov 13, 2012 @ 14:19

            UpdateChunk as you guessed (you basically read my mind), has several annotations per method, for example, if a field will be ONLY stored at Riak, then it is @Transient, if it is a pseudo property then it is annotated with @Transient and @JsonIgnore, so basically I have a hybrid ORM, except that my relational part is very minimal, the idea behind SQL is only to provide a set of indexes for search and filtering purpuses, you could manuall fetch with multiget using the IDs, but I have used Hibernate interceptors before and they are ... lets say they are faster than doing the job manually OR using AOP.

            Lets say, List findBy... will do the whole job, hybridly speaking, my only draw back, which it is a matter of taste, is that I don't like Query DSL, at advanced applications you usually do either of the following things:

            1) Standard JPA repo for most queries (which supports pagination)
            2) Use custom queries either using entity manager and building your own query.
            3) Typesafe using criteria, I like more the Type safe idea because the mapping is resolved, specially if your project has custom mapping like joda time, which by just adding a jar works: @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")

            I have another layer for Riak, which will be called by Hibernate interceptor, with mutation and all that Riak implies, with its own caching (Using Google's Guava 13.0.1 framework) so doing the multiget will kind of have its own 2nd level cache so it will be fast.

            But as you know, Redis, Memcache, CouchDB, and most KV NoSQL DBs tend to have poor indexing/search like API, so we have to have a Hybrid model, we even have Solr 4 which we use for other type of Docs searching.

          • Petri Nov 14, 2012 @ 19:40

            Thanks for explaining the "theory" behind the decision to use the "hybrid" model. It was interesting and I definitely agree that index and search APIs of NoSQL databases tend to be poor (At least when you compare them with relational databases).

        • Stephane Apr 10, 2015 @ 13:06

          Hi Guido,

          You'd have some direction on how I could inject a JPA repository into an Hibernate interceptor ? I would like to log in a table Hibernate operations using an AuditLogRepository but it is not seen by Hibernate.

          Cheers,

          • Petri Apr 10, 2015 @ 19:08

            Hi Stephane,

            I noticed that you asked you the same question here: Spring managed Hibernate interceptor in JPA.

            This gave me an idea. Maybe you can do something like this:

            1. Inject the JPA repository to your @Configuration class or add it as a method parameter to the @Bean method that creates the Hibernate interceptor object.
            2. Implement the @Bean method by creating the Hibernate interceptor. Remember to pass the JPA repository to it.
            3. Follow the instructions given in the blog post I mentioned earlier.

            Naturally I haven't tried this myself, but it could work.

  • Guido Medina Nov 12, 2012 @ 19:20

    Our idea is to use POJO which will be convert back and forth to JSON, stored in Riak NoSQL fully and only few of their properties stay in SQL for query/indexing purposes, so our focus in JPA is just for filtering, paging and stuff, using JPA/Hibernate to update objects and interceptors to populate to Riak, most Objects will just in Riak with few in SQL.

  • Guido Medina Nov 12, 2012 @ 22:18

    Yes, you are right, the source code pointer you sent answers my questions, thanks a million. Now my puzzle is completed, to be honest, it seems like Spring Data is bigger than what I thought, you need another 200 pages from your publisher and an Advanced Spring Data book.

    • Petri Nov 12, 2012 @ 22:42

      Hey, good to know that you found the answer you were looking for! Now I am wondering if my lucky shot described above works. I am wondering if I should test it myself ;)

      • Guido Medina Nov 13, 2012 @ 15:12

        As for the Hibernate interceptor, it is easier to use than what you think, explained on this reference: http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/events.html

        • Petri Nov 14, 2012 @ 19:34

          Thanks for the learning experience. It is always nice to learn new things!

          • Guido Medina Nov 19, 2012 @ 21:22

            I have successfully implemented what I called phase 1, I couldn't do it in Hibernate, I had to switch to EclipseLink 2.4.1 which to be honest for JPA 2+ I think it will have a better future, when you annotate a property with @Transient, no interceptor in the world see the value and hence it is lost for Riak (@PostInsert and @PostSave)

            So EclipseLink as this @CloneCopyPolicy which allows you to specify a method which will create a of your Entity including its transient properties, so this method which I called cloneThis basically creates a BeanWrapper instance and copy each not null property to a new instance.

            To resume, the Entities backed with NoSQL require two additional annotations: @CloneCopyPolicy and @EntityListeners, then magic happens, the entity listener also have methods for @PostLoad and @PostRemove.

            Where can I post or send you my @Configuration class for EclipseLink?, It is almost the same as the one of your tutorial, it requires for a better performance the ReflectiveLoadTimeWeaver which has to be configured at bootstrap at the application servers (Had to google so much)

      • Guido Medina Nov 15, 2012 @ 1:06

        BTW, I finished today most of our new API, finally, I went for EntityListener called JPA2RiakListener, since I don't mind annotating the POJO with the listener class, and it will remove the overhead of calling the listener when an Entity is backed by Riak. It was really hard to create a JPAQueryUtil for count and pagination because of some stupid error with CriteriaQuery and generatedAlias, I meant, making a Generic type like Pageable method where it accept a CriteriaQuery and Order, I had to mix some class and generate the alias by myself, I'll post the code when I give a better form to the code (clean up and stuff)

  • Narciso Aug 17, 2013 @ 5:03

    Hi, after I read your book and and make de tutorials that you brote, we take de desicion to make a project for about 150 enttities, Already finish the construcction of the backend... but in the construccion of the front-end I feel that the team spent too much time. it seems to elaboraiting to much boilerplate. so de question is in sense to suggest me a set of frameworks to acelerate de work?. what do you think about Spring Roo with Spring Data?

    • Petri Aug 17, 2013 @ 10:28

      First, I would like to thank you for reading my book and tutorials. I hope that they were worth your time.

      Could you describe what were the biggest reasons of writing boilerplate code? This would help me to give a better answer to your question.

      However, one very common task that requires boilerplate code is transforming DTO objects into model objects and vice versa. There are several libraries which help you to reduce the amount of required code:

      I have no experience from Spring Roo (I have not used it) so I have no idea if it is useful. The problem of code generation (in general) is that I want to be in control of my code base because this way I know that the code is good enough.

      Code generators can help you to create the skeleton of the application but naturally they cannot write the actual logic for you (except maybe in simple cases).

      This being said, I think that it might be worth to give Spring Roo a shot. You should never judge something which you haven't used yourself.

      There are a couple of "related" Spring projects which you might find useful as well:

      I hope that my answer was useful to you. If you can shed more light on the reasons of writing boilerplate code, I am more than happy to continue this discussion!

  • SNG Oct 5, 2013 @ 3:26

    I am searching for general benchmarks for performance of SPRING DATA. Is there some blog or articles on performance of Spring Data JPA vs just OpenJPA?

    • Petri Oct 8, 2013 @ 17:36

      I am not aware of such blog post or benchmark :( This is a shame because it would be interesting to know the overhead caused By Spring Data. If you happen to find such a benchmark, it would be nice if you could let me know about it.

  • MRV Feb 3, 2014 @ 13:17

    Hello Petri,

    Thank you very much for your articles ....

    If we use spring data JPA , what would be the best UI frame work you would recommend to integrate with this ? We are looking for some thing that can help faster development and also less experienced developers should be able to learn fast.

    JSF/wicket/struts/spring mvc ........ like this a list is being proposed ...

    Regards
    MRV

    • Petri Feb 4, 2014 @ 16:24

      Hi,

      Have you considered using Grails? Although I have no experience from it, it seems to get a lot love from SpringSource right now. Another interesting project is Spring Boot which simplifies the development of Spring powered applications.

      It is kind of hard to say what is the best UI framework because it depends from many factors. For example, if most of your team members already know JSF and have no experience from Spring MVC, it probably makes no sense to use Spring MVC in your project (unless you want to learn something new).

      One suggestion though: I wouldn't consider using Struts because it doesn't offer anything which isn't found from Spring MVC.

      • Vikas Feb 5, 2014 @ 13:59

        Petri,

        Basically we are looking for some thing like SPRING REST, SPRING DATA JPA stack ... but looks like JSF is not a good candidate for the above stack . I may be wrong but.

        Grails looks like( yii php frame work) but couldn't find good tutorials that give enough confidence ..

        • Petri Feb 5, 2014 @ 19:16

          Vikas,

          Maybe you could build your applications by using the "full" Spring stack. In my previous job I did use another web framework (Wicket) with the Spring stack. It seemed to be the right thing to do at the time but now I think that perhaps the "full" Spring stack would have been a better choice.

          • Vikas Mar 10, 2014 @ 11:38

            Petri,

            Do you have any experience on Play frame work ? any idea how good it is when comparing to grails ?

            Regards
            Vikas

          • Petri Mar 10, 2014 @ 12:08

            Hi Vikas,

            I have created a "Hello World" application with Play and Scale so I have no real experience from it. However, I remembered that zeroturnaround.com has published a few rather good articles about Java web application frameworks:

            Maybe these will answer to your question.

          • Vikas Mar 11, 2014 @ 13:50

            Petri,

            Planning to try Vaadin... thank you very much for your directions. Will update you if any road blocks.... just for sharing experience.....:-)

            Regards
            Vikas

          • Petri Mar 11, 2014 @ 20:11

            Hi Vikas,

            I am very interested to hear your opinion about Vaadin. I have an opinion too but I am not going to reveal it yet. :)

  • Vikas Mar 12, 2014 @ 13:26

    Petri,

    As per one of our brain trusts opinion we decided to try vaadin for only admin modules. As it is state full and consumes more memory due to all built-in widgets/components ...We fear whether it may scale to eCommerce kind off apps where traffic is more ...we are now more to the original plan ...

    Some thing like

    Spring data jpa rest mvc + Jquery ...
    Or
    Play + Jquery

    Regards
    Vikas

  • RR Mar 21, 2014 @ 13:45

    Hello Petrik,

    I am very new to the world of Spring and all programming stuff. We use Spring data in our project.
    I have a simple query as follows "select * from USERS". I also use Pageable to enable pagination.

    This query may have optional predicates based on the given parameters being null or not.

    For example if "code" parameter is given and not null, then the query becomes "select * from USERS where code = :code";

    As far as I know I cannot implement this using @Query annotation. I can implement a custom repository and use EntityManager to create a dynamic query. However, I am not sure how I can integrate "Pageable" with that to get back paginated results.

    How can I achieve this?

    • Petri Mar 21, 2014 @ 15:25

      If you need to build dynamic queries, you can use either JPA Criteria API or Querydsl. Both of these techniques support pagination so it shouldn't be a problem.

      • RR Mar 23, 2014 @ 6:02

        Hi Petrik,

        Thanks for the reply, This is how i created my query. Can you please tell me how i can use pagination with the same ?
        I need to return Page instead of collection.

        public List findCustomers(
        final String firstName, final String surname) {

        StringBuilder queryBuilder = new StringBuilder(
        "select c from Customer where ");
        List paramList = new ArrayList();
        paramList.add(" upper(c.firstName) like '%?%'"
        .replace("?", firstName.toUpperCase()));
        paramList.add(" upper(c.surname) like '%?%'"
        .replace("?", surname.toUpperCase()));

        Iterator itr = paramList.iterator();
        while(itr.hasNext()) {
        queryBuilder.append(itr.next());
        if (itr.hasNext()) {
        queryBuilder.append(" and ");
        }
        }

        final Query query = entityManager.createQuery(
        queryBuilder.toString());

        List resultList = (List)query.getResultList();

        // iterate, cast, populate and return a list
        }

        Return a page instead of collection / list, can you please help me with that?

Leave a Reply