Aug 4, 2015
Falsehoods programmers believe about versions
Jul 2, 2015
Single Repository, one Aggregate
Ok, to start out we need our POM (or you can use Gradle), which configures our dependencies and plugins. We use a starter for Spring Data JPA, which pulls in Spring Data JPA and all of it's suggested dependencies such as Hibernate. We also need a database and a database driver so we configure H2. Since we are inheriting from the Spring Platform BOM we don't need to specify versions as it can configure them for us. We of course want to use Java 8 and specify our Application class so we will be able to run
mvn spring-boot:run at the end.
Next Let's configure our application to show the SQL that it is running, this isn't required. You need to put
application.properties in src/main/resources.Now we need to create our Entities, let's start at the entity Bar that is the deepest part of the Aggregate root. It extends AbstractPersistable so that we get an Auto Incrementing or Sequenced id. We also use AbstractPeristable because for our task we require that our entities implement Persistable, as it changes the behavior of save on the repository if your objects are new.
Next let's create Foo, it is much the same, but you'll notice the
@OneToOne that specifies CascadeType.ALL. This is important as without it persist and merge won't work.Alright, let's put together our repository, we could just make a CrudRepository, but let's show off some paging too. You'll notice that you have to pass the Entity and it's Primary Key identifier type to the PagingAndSorting interface, the single method that we specify will find all the Foos by the nested baz property, using a
LIKE '%mystring%' query. Spring data will parse this interface and make an implementation for you automatically.You can create other lastly we do our Application, which is not designed to be a web server (it will exit immediately). The
@SpringBootApplication makes Spring Boot able to start the app and scan for components appropriately. We also Enable JPA repositories using the @EnableJpaRepositories. It's main method (not recommended to prepopulate data this way), creates and save several Foos with nested bars, then I demonstrate a way that you can page the saved objects 2 at a time whilst filtering by that like statement, only 3 of the 4 entities saved will return.
The full source is available here.
Jun 20, 2015
Continuous Integration with Wercker and Maven
First let's talk about what Wercker is and why you'd want to use it. Wercker a continuous integration and deployment web application. It will all you to run any language or stack. It currently is free for both private and public repositories; I am hopeful that once it comes out of beta it will maintain reasonable pricing for small personal private projects (Most CI's are ridiculously priced for hobby projects). It can deploy to any platform.
All this said Wercker accomplishes my need of having a continuous integration environment that is cheap enough to work for both my open source and my private hobby projects, no matter what language I might use.
mvn test at the root. To make this simple, here is a spring boot sample project, you can clone that, and copy the directory I linked into a new project, and create a new git repo and upload it to your git host. Here's a fully configured sample project I madewercker.yml, create that file at the root of your git repo. the first thing the file will need is a box, the box is the docker image your code runs in, and will deploy. For this we'll choose the maven docker image, all you need to do is put box: maven:latest at the top of the file. After that we need to add build steps. build steps are individual units of work you need to do to build your project. There are ways to write script steps or complicated custom steps, but those are for another article. We're just going to add the maven build step I wrote that works for 1, and 2.0 Though it works better for 1 as it supports caching dependendencies and I haven't figured out if that's possible in 2. Below is the completed wercker.yml, steps has a 2 space indentation, the step name has a 4 space indentation and a -, and goals has an 8 space indentation, as mentioned spacing is very important.May 3, 2015
Abandoning all Perl modules
Jan 7, 2015
Premature optimization is not evil
Or rather people should stop saying this because most of the people that say it don't actually seem to actually know what is meant by "Premature Optimization" or how to determine when it is evil. I've heard people say premature optimization is evil to asking. "Is there a 3rd party library that does this more efficiently?" (knowing if there are better options is premature optimization?), "Thinking about architecting your app for horizontal scalability is premature optimization" (it is if the design is significantly more complex, but if it's just between using REST and ensuring stateless (which is about the same complexity up front, but it'd be harder to convert later)), "wanting to do Dependency Injection is..", "making that code easier to read and simpler and thus faster", and on and on. On the other hand, no one seems to think that requiring Redis, Mongodb, and NodeJS because it's webscale is premature optimization, even if the clustering is horribly convoluted and you end up in callback hell (not saying you are, just saying). Basically, you're not asking to do the thing that everyone else is doing, is premature optimization.
So let's talk about what the hell premature optimization is. Premature spending a week making sure you can spin up infinite instances on AWS because someday you might get slashdotted. Premature optimization is writing a method in a less than clear manner because you think it's faster. Premature optimization is rewriting String.format to StringBuilder because StringBuilder is faster. Premature optimization is any time that you write code that is less readable for the sake of performance, or spend an inordinate amount of time ensuring optimizing it without benchmarking to see if it's slow.
I've spent a significant amount of time in the past few months working on optimizing code, why? because no one ever thought about optimization, it never occurred to the author, in one case, that querying the same data from a database that had been previously queried, in a loop, outside of a transaction, was inefficient. It never occurred to the author that not refetching from the database to do an on screen sort every time you sort would be inefficient. Why think about what you're writing? because premature optimization is evil, or at least that's what I'd be told.
Here's are examples of premature optimization that are not evil. I choose to use EnumMap when I'm storing Enum's in a Map, I presume it's more efficient, so I do it, increase in code? a class name to the constructor. StringBuilder is faster than StringBuffer, so when I come across StringBuffer I convert it, increase in code, none. I use dependency injection to wire stateless (or unchanging state) singletons so I'm not constantly creating instances, code increase is use of a DI framework. I use onClick handlers to ensure that things happen lazily, only when needed.
Basically what I'm saying is that "Premature optimization is evil" is sadly used anytime when anyone is even thinking about anything that could remotely be considered optimization. I personally optimize my code for paradigmn/pattern matching the problem first (which leads to 2 and 3), readability second, performance last. Making smarter decisions about how to write your code is not premature optimization.
I think the real "evil" is encouraging people not to think about performance, or to further understand their craft.