Query, #Query, #NamedQuery : SpringBoot vs JPA performance - spring

I am trying to optimize the response time of an endpoint. I am faced with wondering if I should invest efforts in refactoring the code to see how three different approaches perform:
The programmatic class javax.persistence.Query
The annotation javax.persistence.NamedQuery
The annotation org.springframework.data.jpa.repository.Query
As it is, we use Spring's #Query. And the amount of refactoring to be done makes it so that I would rather get some theoretical knowledge before diving into this.
What are the advantages and disadvantages to using each of these three options?
Our stack: Postgres, EclipseLink and SpringBoot.

The javax.persistence.NamedQuery annotation just offers a way of specifying queries at the entity class, instead of e.g. as part of spring-data-repository interfaces (org.springframework.data.jpa.repository.Query). Since it is only the location of the query definition that differs, there should not be much of a perfomance difference between the two options.
The javax.persistence.Query interface is used by the JPA implementations internally, so again there is not much performance to be gained by using it explicitly in own code in some way.
Before digging into that direction, the following things should be evaluated first when optimizing response times:
query speed at the database (are indices used properly?)
number of queries issued by the ORM (e.g. avoiding n+1 problems by specifying reasonable fetching behavior using #EntityGraphs)

Related

Problems using Document.parse over Aggregation static methods in mongo aggregation in spring data

When using aggregation pipeline with mongo in spring-data, we often face complex pipelines. In these scenarios, the Aggregation class provided by spring-data doesn't cover all the possible queries. Granted it covers more queries/functionalities now than when I started using over two~three years ago.
Example of a Document.parse vs Aggregation
Aggregation.newAggregation(
// Document.parse here
aggregationOperationContext -> Document.parse("{ $match: { 'field': " + value + " } }"),
// Aggregation here
Aggregation.match(field, value)
);
These are the list that I came up with about benefits of each method:
Benefits of using Document.parse():
What you write in the query to be parsed, it's what the java driver will utilize. There is less middle-man here.
Allow complex queries (could be good and bad. I've seen people making complex queries while a simple query would've achieved the same result)
Benefits of using Aggregation provided by spring-data
Succinct syntax
Less likely to errors from typos
My point for posting here is that often time, my team and I discuss if there is any real advantage of using the Aggregation class over tossing the Document.parse() with what we need. Is there other things that I didn't list above? Like, performance, easy of testing, etc? I couldn't see in their source code anything obvious to me. Thank you!

Does Spring Data JDBC support inheritance

I am working on a new project using spring data jdbc because it is very easy to handle and indeed splendid.
In my scenario i have three (maybe more in the future) types of projects. So my domain model could be easily modelled with plain old java objects using type inheritance.
First question:
As i am using spring data jdbc, is this way (inheritance) even supported like it is in JPA?
Second question - as addition to the first one:
I could not found anything regarding this within the official docs. So i am assuming there are good reasons why it is not supported. Speaking of that, may i be on the wrong track modelling entities with inheritance in general?
Currently Spring Data JDBC does not support inheritance.
The reason for this is that inheritance make things rather complicated and it was not at all clear what the correct approach is.
I have a couple of vague ideas how one might create something usable. Different repositories per type is one option, using a single type for persisting, but having some post processing to obtain the correct type upon reading is another one.

Is there a generic REST query language for JPA, spring-data, spring-data-rest

Requirements
generic query language that can be used in GET requests to collection resources in REST api to filter the set of resources returned
queries passed in via a "standard" query language and sent over HTTP as request parameter(s) - .e.g /someresource?query=...... or /someresource?a.b.c=2
SQL queries constructed at runtime on the server
tight integration with jpa, spring-data, spring-data-rest - the less code the better.
nested resource and attribute paths available for queries
support for complex operands - EQUALS, GREATER_THAN, LESS_THAN, NEGATION, LIKE, AND, OR, NOT, IN
E.g.
resourceA.attribute1 = "CAT" AND resourceA.subResourceB.attribute2 >= 42 AND resourceA.attribute3 IN ("WHIZ","BANG")
I've investigated four solutions - each getting closer to the goal. Is there some other solution I haven't found or is there no such complete solution out of the box - is the answer to build upon the "REST query language with RSQL" outlined below?
1) spring-data-rest queries
There is plenty of support in spring data for developing complex queries in code, however this requires the developer to be aware of the structure of queries beforehand and to construct the code accordingly.
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#repository-resources.query-method-resource
2) spring-data, spring-data-rest, query-dsl
http://www.baeldung.com/rest-api-search-querydsl-web-in-spring-data-jpa
+ve An excellent fit - thoroughly capable solution with almost zero coding out of the box
+ve deeply nested queries can be constructed and the server generates correct SQL on the fly.
-ve the only operator is EQUALS '=' in order to apply additional operators you need to implement QuerydslBinderCustomizer instances which once again requires the server code to be aware of the complexity of the query in advance.
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/querydsl/binding/QuerydslBinderCustomizer.html
3) Baeldung - "building a rest query language"
http://www.baeldung.com/spring-rest-api-query-search-language-tutorial
basic operations (EQUALS, GREATER_THAN, LESS_THAN)
http://www.baeldung.com/rest-api-search-language-spring-data-querydsl
advanced operations ((EQUALS, GREATER_THAN, LESS_THAN, NEGATION, LIKE)
http://www.baeldung.com/rest-api-query-search-language-more-operations
OR operator
http://www.baeldung.com/rest-api-query-search-or-operation
+ve - getting closer to generic query language
-ve - feels like a demo / POC
4) REST Query Language with RSQL
http://www.baeldung.com/rest-api-search-language-rsql-fiql
+ve - feels like a more complete Query language & associated parser
-ve - unsure of spring integration
There is no generic REST query language for JPA. What you've identified seems to be what is out there, however the low recent activity on querydsl and rsql suggests that you should use caution when adopting them. You will most likely have to support additional changes yourself by forking the projects, especially 5 years from now when for sure the author has moved on to other things.
Some other interesting links:
5) Use annotations to dynamically build queries
https://blog.tratif.com/2017/11/23/effective-restful-search-api-in-spring
maps annotations on a controller method via Spring's argument resolvers to JPA criteria specifications
places SQL concepts like joins in the web controller, which leaks abstractions
should be implemented at a service level not a controller level

Streamlining the implementation of a Repository Pattern and SOA

I'm working with Laravel 5 but I think this question can be applied beyond the scope of a single framework or language. The last few days I've been all about writting interfaces and implementations for repositories, and then binding services to the IoC and all that stuff. It feels extremely slow.
If I need a new method in my service, say, Store::getReviews() I must create the relationship in my entity model class (data source, in this case Eloquent) then I must declare the method in the repo interface to make it required for any other implementation, then I must write the actual method in the repo implementation, then I have to create another method on the service that calls on the repo to extract all reviews for the store... (intentional run-on sentence) It feels like too much.
Creating a new model now isn't as simple as extending a base model class anymore. There are so many files I have to write and keep track of. Sometimes I'll get confused as of to where exactly I should put something, or find halfway throught setting up a method that I'm in the wrong class. I also lost Eloquent's query building in the service. Everytime I need something that Eloquent has, I have to implement it in the repo and the service.
The idea behind this architecture is awesome but the actual implementation I am finding extremely tedious. Is there a better, faster way to do things? I feel I'm beeing too messy, even though I put common methods and stuff in abstract classes. There's just too much to write.
I've wrestled with all this stuff as I moved to Laravel 5. That's when I decided to change my approach (it was tough decision). During this process I've come to the following conclusions:
I've decided to drop Eloquent (and the Active Record pattern). I don't even use the query builder. I do use the DB fascade still, as it's handy for things like parameterized query binding, transactions, logging, etc. Developers should know SQL, and if they are required to know it, then why force another layer of abstraction on them (a layer that cannot replace SQL fully or efficiently). And remember, the bridge from the OOP world to the Relational Database world is never going to be pretty. Bear with me, keeping reading...
Because of #1, I switched to Lumen where Eloquent is turned off by default. It's fast, lean, and still does everything I needed and loved in Laravel.
Each query fits in one of two categories (I suppose this is a form of CQRS):
3.1. Repositories (commands): These deal with changing state (writes) and situations where you need to hydrate an object and apply some rules before changing state (sometimes you have to do some reads to make a write) (also sometimes you do bulk writes and hydration may not be efficient, so just create repository methods that do this too). So I have a folder called "Domain" (for Domain Driven Design) and inside are more folders each representing how I think of my business domain. With each entity I have a paired repository. An entity here is a class that is like what others may call a "model", it holds properties and has methods that help me keep the properties valid or do work on them that will be eventually persisted in the repository. The repository is a class with a bunch of methods that represent all the types of querying I need to do that relates to that entity (ie. $repo->save()). The methods may accept a few parameters (to allow for a bit of dynamic query action inside, but not too much) and inside you'll find the raw queries and some code to hydrate the entities. You'll find that repositories typically accept and/or return entities.
3.2. Queries (a.k.a. screens?): I have a folder called "Queries" where I have different classes of methods that inside have raw queries to perform display work. The classes kind of just help for grouping together things but aren't the same as Repositories (ie. they don't do hydrating, writes, return entities, etc.). The goal is to use these for reads and most display purposes.
Don't interface so unnecessarily. Interfaces are good for polymorphic situations where you need them. Situations where you know you will be switching between multiple implementations. They are unneeded extra work when you are working 1:1. Plus, it's easy to take a class and turn it into an interface later. You never want to over optimize prematurely.
Because of #4, you don't need lots of service providers. I think it would be overkill to have a service provider for all my repositories.
If the almost mythological time comes when you want to switch out database engines, then all you have to do is go to two places. The two places mentioned in #3 above. You replace the raw queries inside. This is good, since you have a list of all the persistence methods your app needs. You can tailor each raw query inside those methods to work with the new data-store in the unique way that data-store calls for. The method stays the same but the internal querying gets changed. It is important to remember that the work needed to change out a database will obviously grow as your app grows but the complexity in your app has to go somewhere. Each raw query represents complexity. But you've encapsulated these raw queries, so you've done the best to shield the rest of your app!
I'm successfully using this approach inspired by DDD concepts. Once you are utilizing the repository approach then there is little need to use Eloquent IMHO. And I find I'm not writing extra stuff (as you mention in your question), all while still keeping my app flexible for future changes. Here is another approach from a fellow Artisan (although I don't necessarily agree with using Doctrine ORM). Good Luck and Happy Coding!
Laravel's Eloquent is an Active Record, this technology demands a lot of processing. Domain entities are understood as plain objects, for that purpose try to utilizes Doctrime ORM. I built a facilitator for use Lumen and doctrine ORM follow the link.
https://github.com/davists/Lumen-Doctrine-DDD-Generator
*for acurated perfomance analisys there is cachegrind.
http://kcachegrind.sourceforge.net/html/Home.html

Spring JDBCTemplate VS Hibernate in terms of performance [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
In our project we have to decide between Spring JDBCTemplate and Hibernate.
I want to know which is better in terms of performance and implementation and design. and how?
If you do all you can to make both implementations very fast, the JDBC template will probably be a bit faster, because it doesn't have the overhead that Hibernate has. But it will probably take much more time and lines of code to implement.
Hibernate has its learning curve, and you have to understand what happens behind the scenes, when to use projections instead of returning entities, etc. But if you master it, you'll gain much time and have cleaner and simpler code than with a JDBC-based solution.
I would say that in 95% of the cases, Hibernate is fast enough, or even faster than non-optimized JDBC code. For the 5% left, nothing forbids you to use something else, like Spring-JDBC for example. Both solutions are not mutually exclusive.
That depends on your project and how well the Hibernate model fits the way you think. Speed/performance is irrelevant: If you can't wrap your mind about how Hibernate works, your project will be riddled with strange bugs that will take ages to find and fix.
Also note that the internals of Hibernate will leak into your model and DAOs. Notable points of conflict are usually equals()/hashCode() and lazy loading of collections outside of transactions. Since the examples with Hibernate are so simple and you can achieve a lot in a short time, this can lead to the misconception that Hibernate is simple. It's not. Hibernate makes a lot of assumptions and forces you to think and code in a certain way.
Using JdbcTemplate is easier because it's just a very thin wrapper around JDBC itself. The price here is that you will write thousands of lines of really boring code. Also, you will find that SQL strings are really hard to maintain. When your data model changes, you will have to search your whole code base for all places which might be affected. It won't be pretty.
For our own project, we decided against Hibernate because we have really complex data structures (revisioned tree structures) and have to build complex search queries at runtime. Instead, we wrote our own DAO layer using jOOQ. jOOQ is a thin wrapper around JDBC which allows you to write SQL with a nice DSL in Java:
create.selectFrom(BOOK)
.where(PUBLISHED_IN.equal(2011))
.orderBy(TITLE)
Like Hibernate, jOOQ has some rules which you should follow or you won't be happy but these are much more lenient.
As another option, you should have a look at Spring Data. In a nutshell, Spring Data allows you to store your data into anything that remotely resembles a database. This means you can manage your model with Hibernate and another using a NoSQL database. Or you can easily migrate part of your model as needed.
One of the key features is that the DAO implementation look like so:
public interface UserRepository extends Repository<User, Long> {
List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
}
Now you may wonder where the implementation is since this is just an interface with a method definition but that's it. At runtime, Spring Data will generate code for you which implements this method. This is possible because 99% of all the queries which you will need are of the form "query table for all rows where column X is ..." so they optimized this use case.
OTOH, if you already know that you're going to build really complex search queries at runtime, Spring Data probably won't be of much help.
In our project, we are using both, JdbcTemplate and Hibernate. What you need to do is share DataSource between hibernate and jdbcTemplate.
We can check performance for both according to operations, whichever is better, we use better one. Mostly we are using hibernate for normal operations, if there are big queries or heavy operations, we check performance for jdbc and hibernate whichever better we use it.
The good point is HibernateTransactionManager works for both (JdbcTemplate, plain jdbc) and hibernate.
Is your database design hibernate friendly? If yes then use hibernate...if not then you may want to avoid it. Jdbctemplate has many upsides and there are ways to make sure your SQL queries are easily maintained. Have a class that holds all of them or read them from a file etc. If columns have to be update there is a way to use standard jdbc to get resultset meta data allowing you to retrieve column names. This can be complex but an interesting way to solve an issue. Hibernate is a great tool but complex data models make it get really tricky.

Resources