Tales from the jar side: Stored procedures in Spring, The secret to happiness, and Clever tweets
Dad joke: I went to a bookstore and saw a book entitled, "How to Solve 50% of Your Problems." I bought two.
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of February 7 - February 13, 2022. This week I taught Week 1 of my Spring and Spring Boot in 3 Weeks course on the O’Reilly Learning Platform, and my Spring Data JPA course as an NFJS Virtual Workshop.
Regular readers of this newsletter are affectionately known as jarheads, and are widely acknowledged to be far more intelligent, sophisticated, and attractive than the average newsletter reader. If you wish to become a jarhead, please subscribe using this button:
Whenever my newsletter becomes too long for email, you can read the full version online. If you miss an issue, the entire archive is there as well, and everything is free and always will be.
Calling Stored Procedures In Spring
One student in my Spring in 3 Weeks course contacted me about an issue she was having with Spring Data JPA. For those who are unaware, JPA is the Java (now Jakarta) Persistence API, and Spring Data is an umbrella project that simplifies all data access libraries using Spring capabilities. Spring Data JPA specifically is for working with relational databases, and uses the open source Object-Relational Mapping (ORM) tool Hibernate to generate and execute SQL on the developer’s behalf.
The problem she faced was trying to call a stored procedure using Hibernate/JPA. I don’t get into that in my regular Spring in 3 Weeks course, but I do talk about it a little in my Spring Data JPA course.
It is possible to call a stored procedure using JPA. For my demo, I use the Sakila sample database from MySQL, which models a video store (kids, ask your parents). Sakila contains a stored procedure called the film_in_stock stored procedure, which takes two input parameters of type integer (the film ID and the store ID), and returns an output parameter of type integer that shows how many those films are in stock at that store.
The sample on the Sakila web site shows:
mysql> CALL film_in_stock(1,1,@count);
+--------------+
| inventory_id |
+--------------+
| 1 |
| 2 |
| 3 |
| 4 |
+--------------+
4 rows in set (0.01 sec)
Query OK, 1 row affected (0.01 sec)
mysql> SELECT @count;
+--------+
| @count |
+--------+
| 4 |
+--------+
1 row in set (0.00 sec)
The idea is that there are 4 copies of film 1 in store 1, so now I have a test case.
It is in fact possible to call this procedure using Spring/Hibernate/JPA. Here’s my FilmRepository interface, which extends JpaRepository with generic types Film and Integer:
To support that, I have this monstrosity on top of my Film class:
The point is to identify the input and output parameters and their data types. My test case then looks like:
That @Disabled annotation is there for a reason. The test worked fine under Spring Boot 2.5.4, but when I upgraded to version 2.6, I suddenly started getting:
Call to stored procedure [film_in_stock] returned multiple results; nested exception is javax.persistence.NonUniqueResultException:
Call to stored procedure [film_in_stock] returned multiple results
That is, of course, ridiculous. I can execute the procedure from the command line and it works just fine, and, as I said, this worked in Spring Boot 2.5.4. Why it would suddenly stop working in 2.6.3, I have no idea.
There’s a bigger issue, however, and for me it’s a philosophical one. The purpose of JPA is map your classes to tables and let Hibernate take over from there. Hibernate was not designed to call stored procedures, and just because it can, doesn’t mean you should use it that way.
Maybe calling stored procedures through Hibernate isn’t “reanimate dinosaur predators and trust everything will be fine” crazy. It’s more of a “if all you have is a hammer, everything looks like a nail” decision.
In my classes, the other bit of evidence I offer is that there’s a book called Java Persistence with Hibernate. It’s nearly 900 pages long. If you look up “stored procedure” in the index, you find one section, covering about 6 pages. Why so little? Because they don’t want to do it. Hibernate wants to convert table rows to objects and back again, and that’s it. Everything else is a distraction. They added the stored procedure capabilities because people asked for it, but just because you can use a hammer to drive in a screw doesn’t mean that’s the best tool for the job.
Spring, on the other hand, also has a class called SimpleJdbcCall, and it’s designed to call stored procedures without all that JPA clutter. Here’s my class using that:
Autowire in a datasource (that’s Java for “database connection pool”), instantiate the class, tell it which procedure you want to call, and call it with the proper parameters. I have to make a separate instance for each stored procedure, but so be it.
Now the test looks like:
This works like a charm, and is much easier both to write and to understand. Even if the other approach didn’t have a bug in it, I’d still rather do it this way.
All my code working with Sakila is in my sakilajpa GitHub repository.
Happiness Is A Warm Puppy
Way back in 1962, Charles Schulz (of Peanuts fame) published the first edition of his book, Happiness Is A Warm Puppy:
I remember reading it in elementary school. I don’t remember much about it, but it went about how you would expect, valuing love and friendship and puppies and similar items.
(On the other hand, Happiness Is a Warm Gun is a song by The Beatles on their self-titled album, which everybody calls The White Album. That’s a bit different, and reflects John Lennon around the peak of his psychedelic drug phase and has, shall we say, somewhat different connotations.)
Last week a long article was published in The Atlantic entitled, How To Want Less, by Arthur C. Brooks. It features an interaction he supposedly had about satisfaction (both the Rolling Stones song and the concept) that he had with his teenaged daughter, which comes across as probably fake but at least wildly unlikely. The article is from a book he is writing (what a shock) and is covered in his podcast on the subject (he has a podcast? No way).
I don’t mean to come across as quite so cynical, but the article is getting a lot of attention and I want to comment on it just a bit. The fact is, I agree with most of it. His basic idea, which he takes over 6000 words to get to, is that our brains are hard-wired to want more stuff, but eliminating desires is what leads to happiness. His recommendations are a combination of Buddhist thinking and Thomas Aquinas asceticism. Live in the moment and be satisfied with what you have, however little it may be.
Yeah, okay. The fact is, I have a whole NFJS presentation on a similar subject, called Mental Bookmarks and The Fractal Nature Of Success, which I’ve been delivering for a few years now.
My thesis is that our society is designed to make you want more, getting you to believe that if you just work a little harder and sacrifice a little more, you’ll finally be happy. Unfortunately, the fractal part is that success at every level looks similar: there’s always a level above, and it’s easy to forget about the levels below. No matter how high you go, there will always be a level higher, and you’ll easily forget about what it took to get to where you are now.
The solution, if there is one, is to be aware of this so it doesn’t govern your behavior. Try to live in the moment.
The best way to say this comes from Master Oogway in Kung Fu Panda, of course:
My talk has a lot of overlap with Professor Brook’s article, but maybe I’m a bit resentful that I don’t have his audience.
Oof. Sounds like I have a desire problem too, but I knew that. Brooks also recommends becoming a teacher (funny you should mention that, too), in a section he calls “Go From Prince To Sage,” which sounds pretentious until you realize he’s talking about the Buddha. The idea is to have something to offer to the next generation, and help them achieve rather than worrying about your own credentials. He says that he gave up a lucrative government job to teach, but of course when he says, “to teach,” he means he is now (pause while I look this up), “a contributing writer at The Atlantic, the William Henry Bloomberg Professor of the Practice of Public Leadership at the Harvard Kennedy School, and a professor of management practice at the Harvard Business School.”
Yeah, big step down there. Way to make a sacrifice of material gains to achieve future happiness. I hope it all works out for you.
Again, sorry for being so cynical. I’ll just finish with this thought. As I get older, one of my fears is that I’ll have a lot say, but nobody will care enough to listen. I therefore want all of you to know — and I’m serious about this — how grateful I am that you’re reading this newsletter, formal jarhead subscribers or not.
The fact that I can simply talk about whatever inspires me during a given week and have many people value the results is worth diamonds to me. I’m very lucky to have such a kind, intelligent, and sophisticated group of readers here. Writing my newsletter for all of you is a highlight of my week, and I’ll continue to do so as long as someone is willing to read it.
Tweets and Things
The Queen Is A Powerful Piece
I thought this was funny:
That Bishop looks safe, though, at least for one move.
How Can There Be Global Warming If It’s Cold Outside?
I trust you all know how silly that question is. This week, however, we hit almost 60 degrees (Fahrenheit) one day and then dropped into the 20s on the next. This image came to mind:
NFT Rants
This too, was pretty funny:
There were several good posts about the chaos of NFTs and cryptocurrencies this week. Read this post for a technical take-down of the most of the related ideas.
This article talked about the fakes and plagiarism problem with NFTs. As quoted in this tweet:
The relevant section includes:
The U.S.-based Cent executed one of the first known million-dollar NFT sales when it sold the former Twitter CEO's [first] tweet as an NFT last March. But as of February 6, it has stopped allowing buying and selling, CEO and co-founder Cameron Hejazi told Reuters.... Hejazi highlighted three main problems: people selling unauthorised copies of other NFTs, people making NFTs of content which does not belong to them, and people selling sets of NFTs which resemble a security.
He said these issues were "rampant", with users "minting and minting and minting counterfeit digital assets".
"It kept happening. We would ban offending accounts but it was like we're playing a game of whack-a-mole... Every time we would ban one, another one would come up, or three more would come up...." Hejazi said his company was keen on protecting content-creators, and may introduce centralised controls as a short-term measure in order to re-open the marketplace, before exploring decentralised solutions.
Best quote at the end: "We realized that a lot of it is just money chasing money."
Here was another good tweet about the whole subject:
But then a dose of perspective:
The Last, Best Hope
This clever bit of word play came up last weekend:
The right answer, of course, is Babylon 5. I tried putting that in, but even though it has the right number of letters (!), it didn’t fit the interlocking clues. (The Expanse had too many letters.) Maybe next time.
Oh Wordle, Wordle, Wordle, I Made You Out Of Clay
I still have mixed feelings that when I go to play Wordle I’m redirected to the New York Times site. On that note, I’ll leave you with this tweet, which links to a couple of YouTube videos:
Grant Sanderson is great, and here he introduces information theory via Wordle. That’s one of those subjects I keep planning to learn but where I never manage to find the time. Seems like a good topic for next year’s NFJS tour, though, unless NY Times has killed Wordle by then.
But today is a gift. :)
Happy Super Bowl Sunday to those who celebrate, and Happy Superb Owl Sunday for the rest:
No reason you can’t celebrate both, of course.
As a reminder, you can see all my upcoming training courses on the O’Reilly Learning Platform here and all the upcoming NFJS Virtual Workshops here.
Last week:
Spring and Spring Boot in 3 Weeks, week 1, on the O’Reilly Learning Platform
Spring Data JPA, an NFJS Virtual Workshop
This week:
Spring and Spring Boot in 3 Weeks, week 2, on the O’Reilly Learning Platform
Java Testing, Part I: JUnit 5 and AssertJ, an NFJS Virtual Workshop
Java Testing, Part II: Mocks, Stubs, and Spies with Mockito 4, an NFJS Virtual Workshop