Two Years On Stackoverflow

It’s going to be my 2nd stackoverflow anniversary on Saturday (the 5th of Novermber, I know, it wasn’t on purpose). A quick summary: I (profile) just entered the top 20 users of all time, and I just provided my 5000th answer. Ranked 3rd in the Java tag. But enough about me – what’s so cool about stackoverflow, that it has become the most popular Q&A programming site so quickly? Many things. I haven’t changed the views that I expressed after my first month, but here are a bit more details from the perspective of an experienced user: learning – there are questions that you can’t answer, and when you see others’ answers, you learn something new. There are questions that you research before answering, so you improve your knowledge. Why do people ask questions that they can also research? Because you have a higher level of general programming knowledge that allows you to look at the right place and find the information. Even if you already know the answer, you get a better understanding when writing it down. Answering questions on SO can be compared to reading blogs that discuss common technical issues. you see where you stand – if others agree with your answers (and upvote them), that makes you feel confident in the topics that you follow. Which is a good thing (if it’s not overconfidence). Questions that people ask show you areas that you probably didn’t know about, but that are important. That way you get a more adequate view of where you stand with your programming knowledge. improving communication skills – (I should have put...

Avoid Lazy JPA Collections

Hibernate (and actually JPA) has collection mappings: @OneToMany, @ManyToMany, @ElementCollection. All of these are by default lazy. This means the collections are specific implementations of the List or Set interface that hold a reference to the persistent session and the values are loaded from the database only if the collection is accessed. That saves unnecessary database queries if you only occasionally use the collection. However, there’s a problem with that. The problem that manifests itself through the exception that in my observations is 2nd most commonly asked exception (after NullPointerException) – the LazyInitializationException. The problem is that the session is usually open for your service layer and is closed as soon as you return the entity to the view layer. And when you try to iterate the uninitialized collection in your view (jsp for example), the collection throws LazyInitializationException, because the session that they hold a reference to is already closed and they can’t fetch the items. How is this solved? The so called OpenSessionInView / OpenEntityManagerInView “patterns”. In short: you make a filter that opens the session when the request starts and closes it after the view has been rendered (and not after the service layer finishes). Some people call that an anti-pattern, because it leaks persistence handling into the view layer, and complicates the setup. I wouldn’t say it’s that bad: generally it solves the problem without introducing other problems. But in all recent project I’ve been involved, we aren’t using OpenSessionInView, and it works fine. It works fine because we aren’t using lazy collections. But then, you’ll rightly point, you will be fetching “the whole world”...

How to map dates with hibernate – use joda-time

This is always a question – how to map temporal data in our hibernate entities – whether to use java.util.Date, java.util.Calendar or simply long. The correct answer is: neither of these. Use joda-time – the de-facto Java datetime API. Using it throughout the whole project is a no-brainer, but how to use it with hibernate – you can’t use @Temporal. Hibernate supports custom types, so there’s a little project that solves the issue – joda-time – hibernate support. The user guide is pretty clear: @Column @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") private DateTime fromDate; However, there’s one issue with that library – it uses static final fields from hibernate, which requires recompilation if the version of hibernate changes (see here). For that reason you may need to extend the PersistentDateTime class, override the 2 methods that use the static final TIMESTAMP field, and copy the exact same code from the superclass. Using joda-time throughout the whole project will save tons of headaches. So I strongly suggest the above mechanism to use joda-time in your hibernate entities as well. This is always a question – how to map temporal data in our hibernate entities – whether to use java.util.Date, java.util.Calendar or simply long. The correct answer is: neither of these. Use joda-time – the de-facto Java datetime API. Using it throughout the whole project is a no-brainer, but how to use it with hibernate – you can’t use @Temporal. Hibernate supports custom types, so there’s a little project that solves the issue – joda-time – hibernate support. The user guide is pretty clear: @Column @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") private DateTime fromDate; However, there’s one issue with that library...

Google App Engine and Maven

I created a small project that I wanted to host somewhere for free. Amazon free tier or Google App Engine? I already have experience with AWS, so I decided to try GAE. It is completely different, of course. And it didn’t start quite well, with some NullPointerExceptions from the eclipse plugin. But ultimately, it worked fine. However, I was a bit confused how to use Maven in a GAE project. By default, everything should go to the /war directory, and that’s not maven’s directory structure. And this post scared me even more – the pom.xml looks appalling. What I ultimately achieved is workable, and the pom remains simple. mavenzie your project (m2eclipse). Update project configuration to have everything in place In right click > Properties > Google > Web applications have the path pointing to “target/project-0.0.1-SNAPSHOT” (or whatever your assembly folder is), and uncheck the “launch and deploy from this directory”. Move everything from “war” to “src/main/webapp”. Parhaps without the jars, which you can add as maven dependencies run maven > package, so that the target directory is populated Right click > Deploy to Google App Engine – it will ask you for a directory the first time – choose “…/target/project-0.0.1-SNAPSHOT” again (this is absolute path). It will remember this decision, but don’t commit the .settings/com.google.gdt.eclipse.core.prefs, because it now contains an absolute path That way everything works fine. Before each deploy you should make a maven build, but that’s not that bad (well, generally speaking, it is bad, but you don’t have hot-deploy here anyway. And my build is really quick. If I had a huge project with a...

How to Handle Project Configuration

Every web project needs some environment-specific configurations. Database credentials, root url, smtp settings, to name a few. It’s a recurring question on stackoverflow, and I’ve seen a lot of variations on the topic, and here I’ll describe the one that I think is best. put all such properties in a .properties file (for example application.properties) have that application.properties sitting outside the web application. It is not bundled with the build provide a command-line option that indicates where that file is located. For example -Dconfig.location=/home/you/config on application startup (in a ServletContextListener usually) load the file and put it in a map. Can be java.util.Properties or a HashMap for spring users – use <context:property-placeholder-configurer location="file://${config.location}/application.properties" . Other frameworks will likely have some mechanism for loading such global properties hold a skeleton properties file in the SCM repository. It should contain all properties, but their values are irrelevant – they will change on each environment the ops team is likely to benefit from versioning different environment configurations (production, qa, stage), so a separate /config folder/subproject can be created and all environment-specific properties can be stored there. When adding a property developers should go and update all files accordingly properties that are not dependent on the environment, but are still global for the project, can be stored within the project (src/main/resources for maven), and committed to SCM. They can be merged with the external properties on startup (merged in memory, that is) most of the externalizable properties can have reasonable defaults – the smtp server of the company, the database driver, etc. They can be placed in a application-defeault.properties within the project, and...

What to Do With IDE Project Files

Each IDE generates its specific project/config/build files. Eclipse generates .project and .classpath, and also the .settings directory. IntelliJ IDEA has its .iml files. And it is always a question what to do with these files in terms of source control management (SVN, CVS, git, etc) The generally accepted practice is to add them to the SCM ignore list (svn:ignore for example). Why? the project does not become aware of the IDE it is developed in. Each team member can use an IDE of their choice there is no danger of sneaking absolute path configurations into the repository no developer can override the local settings of other developers This practice makes sense, but it has one major drawback – the complexity of setting up a project has to be repeated every time. In other words, you can’t start developing immediately after you checkout – you have to configure tons of things – deployment on local server, checkstyle configurations, plugin configurations, etc. Joel Spolsky insists on having a one-step build. Using a build tool instead of the IDE build process is preferable (ant, maven). But in addition to that you should also have a one-step development environment setup (apart from installing a database/search engine/etc.). So how to do that? I know this is an unpopular advice but: commit the IDE project files in the repository. Once a member has a successful local setup, the files should be committed so that everyone else can just checkout/update, and get the project running. I’m sure everyone has gone through the trouble of helping set up the project for new team members, or when getting...