Skip to main content

Part I : A Simple and Smart SQL Result Mapper

I am not at all a fan of ORM solutions/frameworks like Hibernate. I have already written and presented my view on different forums and discussions the reasons for my disliking. I truly empathize with Ted Neward that ORM are “Vietnam of Computer Science”.
http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html
http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx
Followup - http://blogs.tedneward.com/2006/06/27/Thoughts+On+Vietnam+Commentary.aspx
http://stackoverflow.com/questions/404083/is-orm-still-the-vietnam-of-computer-science
Some counter punches
http://www.codeproject.com/KB/architecture/ORM_Vietnam.aspx?display=Print

  • I am not convinced as to why should I learn HQL or similar QLs provided by other OR Mapping solutions? Why should I not write and benefit from SQLs which have been proven to be so powerful over the ages and often outlive the lifetime of an application. So many times I have seen SQLs and Stored procedures being reused as applications moved from say .NET to Java and vice-versa.
  • There is significant learning curve to an ORM add to those fancy concepts like lazy loading(if you need lazy loading you must first think that there is some problem, why are you afraid of object creation with modern day JVM and hardware or is it that you fear you will create too many objects?).
  • Why do I generate, tweak so many XMLs worry about so much XML based syntaxes, how do I efficiently manage these XMLs and alter later if required? There are too many XML elements and attributes some hidden undocumented? Oh this is real pain. Annotations solve some of the meta data hell, but I am still in a dilemma if mixing meta data with code is a good practice?
  • Why do think of my joins in terms of objects when they are best done with relational tables? Sorry I can only think of joining tables and not my objects.Live and let them live in their own world.
  • There is no doubt ORMs are powerful and tries to make life easy. But the learning curve and deadline pressures often forces developers with somehow acquired knowledge by reading few articles and getting started guides from here and there to code and then finally when issues crop up especially too many objects, JVM crashes and sever performance worries the application falls apart and you focus more on solving these than business logic.
  • Even dangerous trend that I see these days is the advent of ORM specific profilers. What does this imply? Yes the ORMs are serious cause for performance bottlenecks in your applications. I know someone came to me few months back, asking why his JVM crashes when he is running his search queries and paging? His table just had about 150k records and JVM heap was 2GB. Not a bad setting at all? Is it because the ORM was fetching a significant subset of the records based on the search criteria,first to application server before starting pagination? or my friend had a bad QL statement?
  • I know ORMs can help with optimistic lock? But do they help with phantom records problem?
  • Why should I cache on application server and allow or create a slightest possibility of my JVM to burst? Does caching on JVM really increase the application performance? I always knew and still continue to believe the best place to cache database records is in the database memory. Can we not gain on performance by keeping these data to where it belongs, which have been long tuned and proven to optimize performance, reducing network trips, setting tips to bulk fetch data when required, fetch data in optimal blocks? You may be tempted to use caching systems which hides behind the ORM. But think in case of an issue you have the pain of learning another framework and then fixing your errors, if Googling does not help.
  • How does your ORM populate the object graph? Does it fire query after query going down the graph? If yes think about the domain model? Or think about your ORM implementation? Is there any way out? My answer is yes, smart SQL + smart mapping. I will try to show this with an example.
  • However, ORMs are good, if you have indepth knowledge of the framework under consideration. Then with an ORM you can significantly cut down code in your DAO layer. This is also a myth. With Spring JDBC you can reduce your code even more or equal to what you can with an ORM. You can read an article I wrote long back on OTN(actually wrote in erstwhile BEA DEV2DEV) here to start thinking about this - http://www.oracle.com/technology/pub/articles/dev2arch/2006/10/spring-jdbc-dao.html
  • One area I thought I might use ORM is when I design a product which needs to support multiple databases. But then I realised this is not true, if we manage to externalize our SQL and have an efficient strategy to map SQL result set to our domain object we can achieve database independence. 99% of the applications are not meant to be db independent. If your customer has investment so much money to procure license, build competency buy hardware for that big blackbox for Java developers called RDBMS why would he want that box of money, time and effort go down the drain by replacing it with another. So if you are trying to sell me an ORM for db independence I will not simply not buy in.
  • ORMs dependent on several 3rd party libraries. Do I need to increase 3rd party dependencies? Yes you will need 3rd party jars but we must make effort to keep them to minimal. There may be version collisions between 3rd party libraries used by your ORM and main framework.

Comments

Popular posts from this blog

Why do you need Spring Cloud Config server?

Last month I wrote a primer on concepts around 12 factor app. Before getting into the details of the Spring Cloud Config Server, I must refresh on the principle #3 from the list presented in that post.

3 – ConfigurationStore config in the environments
Configuration information must be separate from the source code. This may seem so obvious, but often we are guilty of leaving critical configuration parameters in the scattered in the code. Instead, applications should have environment specific configuration files. The sensitive information like database password or API key should be stored in these environment configuration files in encrypted format.
 The key takeaways from this postulate for a cloud-native microservices application are:
Do not store configuration as part of the deployable unit (in the case of lead microservice - inside the jar or war if you are still deploying war like the good old days). Instead, store it in an external location and make it easily accessible during run-…

Upgrading Lead Microservice - Use MariaDB and Flyway with Spring Boot

So far I have been using an in-memory H2 database or Mockito for testing the lead microservice. To make the transition towards using the Spring Cloud Config server, I need to upgrade the micro-application to use MariaDB. I will be adding the configuration in the application.yml  the file which in the subsequent post will move over to the config server store. I will also be using Flyway to make it easy to maintain the database schema changes in future. I will use this post to introduce Flyway in the mix. Spring Boot also provides first class integration with Flyway. I am using Flyway as its really quick and easy to get started, minimal learning curve (no DSL) and I am comfortable with it having used it in the past.

Assumptions

MariaDB 10 is installedBasic familiarity with FlywayHeidi SQL client is installed.
Step 1 - Update build.gradle to include the MariaDB JDBC and Flyway dependencies.
Do not forget to do a Gradle refresh on your IDE (I am using STS 3.8.4 on Java 8)

Step 2 - Rename the…

Part 3 - Integrating Tiles, Thymeleaf and Spring MVC 3

In this post I will demonstrate how to integrate Apache Tiles with Thymeleaf. This is very simple. The first step is to include the tiles and thymeleaf-tiles extension dependencies. I will include them in the pom.xml. Note we wil lbe using Tiles 2.2.2Listing 1 - parent/pom.xml --- thymeleaf-tiles and tiles dependencies <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Tiles -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->

<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-template</artifactId>
<version>${tiles.version}</version>
<scope>compile</scope>