Tales from the jar side: ResponseEntity in Spring, Microfiction and song lyrics, Separating from Gradle, and funny tweets
Two antennas got married. The wedding was okay, but the reception was incredible!
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of July 31 - August 7, 2022. This week I taught week 3 of my Spring and Spring Boot in 3 Weeks course on the O’Reilly Learning Platform, and my Spring MVC Framework course and an NFJS Virtual Workshop.
Regular readers of this newsletter are affectionately known as jarheads, and are far more intelligent, sophisticated, and attractive than the average newsletter reader. If you wish to become a jarhead, please subscribe using this button:
As a reminder, when this message is truncated in email, click on the title at the top to open it in a browser tab formatted properly for both the web and mobile.
Static ResponseEntity methods in Spring
For new readers: This is the technical part of this week’s newsletter. If you’re not interested in that, feel free to skip it. It probably belongs in a blog post anyway, and eventually will be.
The biggest benefit to using Spring Data JPA is that you can extend a single interface and Spring will generate your entire data access layer automatically. Spring Data offers an interface called CrudRepository<T,ID> (“Crud” stands for “create, retrieve, update, delete,” which are the operations you do with a database) for that purpose, which contains a dozen methods, ranging from count()
, which returns a long representing the number of instances in the database, to save(S entity)
, which takes an entity and returns it again, possibly modified (like having a generated ID that was set during the save operation), and more.
The method I want to focus on it called findById(ID)
:
Optional<T> findById(ID id)
The method returns the entity with the given id
, wrapped in an Optional
, or an empty Optional
if the id
does not exist in the database. (It also throws an exception if the id
is null
, but that’s not the issue here.)
This makes sense, and is a correct usage of the Optional
class introduced in Java 8. The question I want to deal with is, if I’m calling this from a REST controller (through a service, but that’s just another layer), what do I do with the result? If the Optional
contains a value, I want to return it and set the HTTP status code to 200 (a successful request), and if the Optional
is empty, I want to return an empty response and set the response code to 404 (not found).
Here’s one way of implementing that in a controller:
(Note: my ProductService
has a method called findProductById
, which just delegates to the repository’s findById
method and returns the Optional<Product>
result.)
That’s doable, and takes advantage of two of the static methods in ResponseEntity
(ok(body)
and notFound()
) but IntelliJ (correctly) suggests that the if
block can be replaced with a more functional approach involving the map
method on Optional
:
The ok
method on ResponseEntity
wraps the returned object and sets the status code to HTTP OK (200), and the static notFound
method sets the status to 404, as needed. The orElseGet
method in Optional
invokes its Supplier
argument only if the Optional
is empty, which is just what you want in this case.
As it turns out, however, there’s another alternative. The same class includes a static method called of
, which reduces all this (including finding the product) to a single line:
Sweet. The docs for the of
method say:
A shortcut for creating a
ResponseEntity
with the given body and the OK status, or an empty body and a NOT FOUND status in case of an Optional.empty() parameter.
Perfect. It’s great when the API gives you a short-cut method that provides everything. The name of the method (of
) is a bit non-obvious, but makes sense once you know about it.
(In the training class I also discuss a third option, which is to throw a ProductNotFoundException
for missing ids, and to use a class annotated with @RestControllerAdvice
to map that exception to the 404 status code and a customized response message (in JSON form). That’s convenient if you want to customize the returned JSON string. Just FYI.)
All this code can be found in the GitHub repository for the shopping app.
Flash fiction and Nostalgia
A wise man once said:
Somebody’s knocking at the door. Somebody’s ringing the bell. Do me a favor? Open the door, and let 'em in.
Flash fiction is usually defined as a story in 1000 words or less, but in these Twitter- and TikTok-driven days, that seems like too many. Microfiction restricts the writer to only 100 words or less.
The most famous example is (falsely) attributed to Ernest Hemingway. Legend has it that he bet several other writers at the famous Algonquin writer’s workshop that he could write a novel in six words. He then wrote on a napkin:
For sale: baby shoes, never worn.
and collected his winnings. Very sad, but it really is a complete story in only six words. When I first read about that story (about that story), I couldn’t check whether or not it actually happened, but now we have this thing called the Internet, and apparently it was a story made up by some editor years later based on an earlier story.
The first book I ever read on short story writing was by Damon Knight, who wrote, among other things, the story To Serve Man that was adapted into a famous Twilight Zone. In his book on writing, he included a story trying to illustrate the nature of science fiction, which I think went like this:
The last man on Earth sat in his house, alone.
There was a knock on the door.
Knight used that as an example of meaning. A story, to be a story, has to have meaning, and those two lines had plenty of meaning. I get it, mostly, but I’m still not completely sure I understand what he was after.
Here is my own example of microfiction, which I’m sure I adapted from other, similar examples but can’t find the original source:
The reply read, “Please allow us 10 days to remove you from our mailing list.”
Oh, yeah? Please allow me 10 seconds to add you to my spam filter.
Maybe I should submit that somewhere, but again, it’s almost certainly not my original idea.
How about this one, which I also think I saw in some form online:
She scowled at me and demanded to know why I was still wearing a mask, when the pandemic was over and they didn’t help anyway.
I smiled sweetly and said, “Condition of my parole.”
She left me alone after that.
(I know what my wife’s reaction to that story will be — how can she see you smile if you’re wearing a mask? But I still think it’s funny. Also, I was going to name the woman Karen, for obvious reasons, but I decided I liked it better if she’s just an obnoxious stranger.)
My stories tend to come from real life. For example: Back in college my girlfriend Jennifer and I were at a restaurant on a Saturday night when Billy Joel’s Just The Way You Are started playing. At the time, that was considered an incredibly romantic song, so I got my hopes up, but she objected to the part where he sings:
I don’t want clever conversation.
Never want to work that hard.
She thought it implied Joel only wanted a woman who wasn’t smart enough to have clever conversations. I pointed out that the next two lines are “I just want someone that I can talk to. I love you just the way you are,” and that if she wasn’t smart she wouldn’t be worth talking to in the first place, but Jennifer didn’t find those arguments convincing.
I told her she was being absurdly paranoid, looking for problems where they didn’t exist … not out loud, of course. At the time I may not have had the relationship experiences that I have now, but I’m not an idiot. I also didn’t enjoy arguing with romantic partners who held veto power over date night evening events, if you know what I mean. But I was thinking it.
Telling stories in few words reminds me of song lyrics, and, as so many things do, that brings me to Paul McCartney. In the early to mid 1980s, after filling in my Beatles collection, I became a McCartney completist. That meant I bought all of his albums, but I wasn’t a collector. I didn’t care about special or collector’s editions or anything like that. I just wanted the songs. Nowadays that would be easy to arrange, because I could just use a streaming music subscription to line up the albums one by one, but back then, if you wanted the music, you had to buy the album.
That meant I acquired all the albums from McCartney (1970, announcing the break-up of the Beatles), to Flaming Pie (1997), when his voice had deteriorated beyond what I could ignore. I even used one of his album covers in a presentation I made as a graduate student at Princeton:
My talk was on computer models of fluid-structure interactions at transonic speeds (i.e., vibrating wings at the speed of sound, get it?), and I couldn’t believe he’d made an entire album just for a gag in my talk a decade later.
FYI, that’s the album with Silly Love Songs and Let 'Em In (quoted above), on it.
Paul’s lyrics have almost never had any significance. He picks whatever words sound good at the time, and he even introduces questions that never get answered.
Love is fine, for all we know.
For all we know our love will grow.
So won’t you listen to what the man said?
He said do do do, do do do do do.
For crying out loud, what did the man say, Paul? It can’t just be do do do, do do do do do, can it?
Last year for the holidays, my wife gave me a nice hard-bound edition of The Lyrics: 1956 to the Present, which talks about Paul’s thinking process on hundreds of songs, from Beatles to Wings and beyond.
Guess what? Listen to What the Man Said isn’t included. Argh! The song went to Number 1 on the Billboard Hot 100 in the US in 1975, and he didn’t bother including it in his lyrics book.
(Okay, okay. I expect what he’s implying is that “the man” believes that love is fine, for all we know, for all we know our love will grow, but if that’s true, the way he phrased it is very misleading.)
Another mystery I wonder about: Paul claimed, “My love does it good,” but does she also do it well? I mean, I assume so, but what does “does it good” even mean in that context, as opposed to doing it well, which I can probably imagine? He then follows up with “whoa-whoa-whoa-whoa, whoa-whoa-whoa-whoa,” and does that mean what it sounds like it means? I guess we’ll never know.
Look, I get it. Not everything has to be loaded with meaning, and even if there is meaning, it doesn’t have to be terribly profound. Some people just want to fill the world with silly love songs, and what’s wrong with that?
But (and finally I’m getting to the point), Sir Paul is 80 years old, and that’s getting up there. When he goes, I’m going to be left with all these questions (and a metric ton of wonderful music — and a metric ton of awful music, but that’s actually not a bad ratio). I’m also going to be very sad, and these days I think I’m spending too much time thinking about that.
Speaking of endings, let me say something about my relationship with Gradle, Inc.
Goodbye, Gradle
One of the managers at Gradle who I’ve known for years asked to speak to me this week. Gradle has been extensively revising their training materials, which is a good thing. To show how serious they were about it, they hired at least one person to do the revisions and potentially change the entire sequence of (free) courses they offer. I spoke to that person a few months ago, shortly after he was hired, and he said very nice things about the job I’ve been doing teaching their Introduction to the Gradle Build Tool online over the past several years.
In case you’re not aware, I’ve been teaching their introductory classes for many years. I was also involved in creating some of their Getting Started Guides, which are short exercises to get you up and running on specific topics. After that project was completed, they asked me to teach the Intro course online, in two consecutive days of four-hour blocks, on a regular basis, and I’ve been doing that every other month since 2017. I’ve been through a couple of revisions of the materials, any many, many versions of Gradle, during that time.
Now, at long last, they had hired someone to revise the entire curriculum. During our conversation, he pointed out how he had a sequence of one-day courses planned, and the first one was starting this month (August). (Next week — August 9, to be specific, if you’re interested.)
When the manager wanted to talk to me, my question was, where do I fit into the new structure? What did they want me to do, both in the short term and the long term?
I have to admit, I wasn’t expecting the answer, which was that now that they had a full-time employee working on the materials, they wanted him to teach the courses going forward. In other words, thanks, great job, and you’re still a “friend of the family” as I like to call it, but they didn’t need me for the regular courses any more.
To be honest, my first reaction was a bit of relief. The existing materials aren’t great, and I’m really glad they’re being updated, but I wasn’t looking forward to cramming everything I liked to cover into a single day. Also, the rate I was charging them hadn’t changed from the day I started, and it’s on the low side.
It’s true that I am a friend of the family. I like the technology, which (though they don’t often acknowledge it) came out of the Groovy programming world, which I really enjoy. Gradle has helped me a lot in my technical career. I even wrote a book about it, called Gradle Recipes for Android, and even though the Android parts of that book are dated, the Gradle parts still hold up pretty well.
Once I realized what the manager was saying, I made it easy on him. I thanked him for the opportunity, assured him I will still be available if they have future needs, and all that. They’ve been good to me, and this definitely wasn’t personal, or even professional regarding the job I was doing. They just decided to bring their training in-house, as they say, and I can hardly blame them for that. We parted on good terms.
But after the call was over, a sense of loss hit me. They’ve been a regular client for over a decade, and I liked being associated with them. Everybody I’ve met there has been friendly and helpful, at least to me, and I believe in the job they’re doing. That’s just life as a contractor.
But it still feels rather sad, which no doubt makes sense. My ongoing relationship with them, which forced me to stay up to date and involved with the technology, is now over. Heck, I could even switch to Maven if I wanted, but I won’t, because, ugh, Maven.
At this stage of my career, and really in my life, I’m expecting this to happen more and more. I’m trying to prepare myself for separations like this, but maybe I shouldn’t dwell on it as much as I do.
Speaking of endings, one of the best baseball announcers of all time, Vin Scully, passed away this week. As his Twitter account said on the day of his retirement back in October of 2016:
I can totally hear that in Vin’s voice, and if you’ve ever listened to him, I expect you can too.
Believe it or not, the very next day after my call with Gradle, I got an email requesting a private Gradle training course. When I asked for more information, they listed a set of topics that ranged from the extremely advanced to the nearly quixotic, which is not unusual for training requests. We’re negotiating, but it was a nice reassurance from the universe that I should stay involved.
I used to tell my son that when you’re in a good situation, be sure to stop a moment to enjoy it, because it won’t last. You will change, and people around you will change, and the world itself will change. It took me until my 40s to find a career I enjoyed, and I’ve been through many changes since then. This is just another one.
Fortunately, my two regular public clients, the O’Reilly Learning Platform and the No Fluff, Just Stuff conference tour, are still around and giving me enough work to keep my one-person company going. I’m also glad I have this newsletter, so I can keep in touch with all of you as well. :)
Random Tweets
Seems fishy
The D Koi gets me every time.
Geeky But True
What they mean, of course, is:
i -= -1;
In other words, replace i
with the value that comes from subtracting -1, which is the same as incrementing by 1. I’m definitely going to use the version from the image some time, but when I do, it is guaranteed to come up on a code review.
Remember: If you like the other developer, it’s pair programming. If you don’t, it’s code review.
Geeky Math
A couple of the comments to that tweet explain why that happens, which I won’t repeat here. Fun, though.
I totally understand this
The struggle is real.
Puns are the lowest form of humor
You don’t see too many -ary vs -ery jokes. See this explanation of the difference between stationary and stationery if you like.
Speaking of bad jokes
I can’t help thinking of the Mighty Thorfish, which is probably a swordfish with a lithp.
As bad as that joke is, I googled it and found this:
I have no explanation for that, and I don’t really want one.
Reverse Marketing
Yeah, please don’t buy my books, either:
Mockito Made Clear, currently in beta
Have a nice week, everybody.
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:
Week 3 of Spring and Spring Boot in 3 Weeks, on the O’Reilly Learning Platform
This week:
Managing Your Manager (APAC time zone), on the O’Reilly Learning Platform
Modern Java: Functional Programming with Streams, Lambdas, and Method References, as an NFJS Virtual Workshop