Vlad Mihalcea

Teaching is the best way to learn

Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly. Hypersistence Optimizer is that tool!

Introduction

Software development is all about knowledge, and nowadays the number of things a programmer needs to know skyrocketed. Most of the time developers are hired by matching their current skills with some project requirements. The project eventually ends, and the developer is assigned to a new project, sometimes using different technologies than what he was previously hired for. What’s the policy for training this guy to deliver his best the soonest possible?

Usually, training and coaching are left-out, so each programmer is on his own. Every time we leave things to chance a huge risk is implicitly undertaken. I believe we should give more to training and coaching and see them more of an investment rather than a spending.

Read More

Why I never blame open source projects

Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly. Hypersistence Optimizer is that tool!

Every now and then I get to read someone’s bad thought towards a given open-source framework. When I started programming Struts web framework was at its prime, everybody loved it. But then, little by little people started blaming it and then hate followed.

Then people started blaming Hibernate and recently MongoDB. I’ve even read that “I shouldn’t use MongoDB“. Well, I delivered projects on Struts, Hibernate and MongoDB, and none of those was ever a blocker.

If there is someone to blame it’s usually us, not the frameworks we use. If you download and browse the source code of a given open-source project, you’ll be pleasantly surprised by the quality of code. Most of the time I find it at least as good as I’d do it myself. Many open-source projects are the result of endless hard-working hours of many passionate developers, so why should we blame their frameworks then?

Like any other thing on earth, all of those have strengths and weaknesses and it’s us to decide which features fit in our projects, or whether we should even consider employing the framework after all.

While learning Struts, Spring or jQuery wasn’t that difficult, when it comes to databases, Hibernate and now NoSQL things get trickier. Both Hibernate and MongoDB are quality products, and I know many successful projects built on top of them, but that doesn’t mean they are easy to use. If you want to employ them, be prepared to learn a lot, there is no other way.

When I started using Hibernate I was overwhelmed by its complexity. I soon understood I couldn’t catch things up without thoroughly studying it, and that’s why I decided to fully read all the 900 pages of Java Persistence with Hibernate. And that was just the beginning, as even now I continue reading and checking its source code every now and then.

Then MongoDB seemed like a good fit in many of our projects, and since I knew nothing of NoSQL, I had to invest quite some time to be productive. Luckily MongoDB offers free online classes and once again I had to get back to studying. If you ever had to work with MongoDB aggregation framework you know what I mean.

Read More

How to retry JPA transactions after an OptimisticLockException

Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly. Hypersistence Optimizer is that tool!

This is the third part of the optimistic locking series, and I will discuss how we can implement the automatic retry mechanism when dealing with JPA repositories. You can find the introductory part here and the MongoDB implementation here.

JPA requires running the Persistence Context code inside a Transaction, and if our Transaction Manager catches a RuntimeException, it initiates the rollback process. This makes the Persistence Context unusable since we should discard it along with the roll-backed Transaction.

Therefore it’s safer to retry the business logic operation when we are not within a running Transaction.

For this, we altered our @Retry annotation as

public @interface Retry {

    Class<? extends Exception>[] on();

    int times() default 1;

    boolean failInTransaction() default true;
}

We here added the failInTransaction property which is set to true by default.

Read More

Optimistic locking retry with MongoDB

Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly. Hypersistence Optimizer is that tool!

In my previous post I talked about the benefit of employing optimistic locking for MongoDB batch processors. As I wrote before, the optimistic locking exception is a recoverable one, as long as we fetch the latest Entity, we update and save it.

Because we are using MongoDB we don’t have to worry about local or XA transactions. In a future post, I’ll demonstrate how you can build the same mechanism when using JPA.

The Spring framework offers a very good AOP support and, therefore, it makes easy implementing an automatic retry mechanism, and this is how I did it.

Read More

MongoDB optimistic locking

Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly. Hypersistence Optimizer is that tool!

Introduction

When moving from JPA to MongoDB you start to realize how many JPA features you’ve previously taken for granted. JPA prevents “lost updates” through both pessimistic and optimistic locking. Optimistic locking doesn’t end up locking anything, and it would have been better named optimistic locking-free or optimistic concurrency control because that’s what it does anyway.

Lost updates

So, what does it mean to “lose updates”?

A real-life example would be when multiple background tasks update different attributes of some common Entity.

optimisticlocking

In our example, we have a Product Entity with a quantity and a discount which are resolved by two separate batch processors.

  1. the Stock batch loads the Product with {quantity:1, discount: 0}
  2. the Stock changes the quantity, so we have {quantity:5, discount: 0}
  3. the Discount batch loads the Product with {quantity:1, discount: 0}
  4. the Discount changes the discount, so we have {quantity:1, discount: 15}
  5. Stock saves the Product {quantity:5, discount: 0}
  6. Discount saves the Product {quantity:1, discount: 15}
  7. the saved quantity is 1, and the Stock update is lost

In JPA you may provide the @Version field (usually an auto-incremented number) and Hibernate takes care of the rest. Behind the scenes there is a safety mechanism that checks the updated rows number when given a specific version. If no row was updated, then the version has changed and an optimistic locking exception is thrown.

Read More

Want to run your data access layer at warp speed?