I did some badness today.
I wanted an integration test to check to see if my @Transactional method actually did rollback on an optimistic lock failure. It’s a pretty business critical method so I wanted to be sure that the whole @Transactional and @Version annotation voodoo actually works.
The approach I took was to inject, what I called a “slowRepository” into the object with the @Transactional method. The slowRepository is just a mockito mock of the object which “answers” (using “thenAnswer”) to the “findBy…” with some custom code.
The idea is that at some point during the @Transactional method the slowRepository is called and the “answer” code is invoked. In the test, the answer code follows along the lines of:
1. Grab the data it requires from the (not slow) repository (the repository the slowRepository is mocking)
2. Switch back the slowRepository for the not slow repository
3. Invoke the @Transactional method again on a separate thread
4. Sleep for a bit
5. Wake up and return the data from step 1
The @Transactional call on the separate thread completes and commits before slowRepository wakes up. When it does, slowRepository returns stale data and the @Transactional method then fails accordingly.
The problem I encountered was using the setters for my @Autowired dependencies on the bean with the @Transactional method. I needed to use the setters so that I could switch in and out the slowRepository, but couldn’t because Spring AOP proxies are implementations of an interface, not subclasses (by default – yes I realise you can get Spring to proxy the target class using CGLIB). I found this blog post which explains how to get at the target object behind a Spring proxy. I converted it to Scala:
…which is pretty ninja.
I’m working on a project using Scala, Spring, JPA and FreeMarker (as you probably guessed from the title of the blog post). I love working with Scala because for the most part, it makes my code more succinct and it is really exciting to work with. I mean, there are obviously other reasons but those are two big ones.
What I don’t like is having to convert between Scala and Java equivalents, but sadly it is unavoidable. The scala.collection.JavaConverters and scala.collection.JavaConversions objects make this a lot easier through implicit and explicit conversions but it does make you wonder what the performance hit is…
I mostly choose to ignore that there is a performance hit – performance problems are a happy problem anyway right?…and at the moment the benefits of being able to write code in Scala greatly outweigh any of my worries.
I use Scala types wherever possible in this project i.e. List, BigDecimal etc. but sometimes it’s just not possible. My domain objects have to use Java types because the JPA vendor doesn’t know how to translate the Scala types into SQL column types. The same goes for objects that are going to be passed to FreeMarker. FreeMarker cannot iterate over a Scala list using the <#list scalaList as item> syntax as you normally would since it doesn’t “know” what a Scala List is. As far as FreeMarker is concerned a Scala List is a java.lang.Object (see scala-lang.org/node/71).
My repositories are generated dynamically by Spring. Basically you define an interface and Spring magically generates a class that extends Spring’s JpaRepository and implements your interface. There is no two ways about it, I want this magic, but it means that the “interfaces” (which are coded as traits in Scala) have to return Java lists for findAll or findBy operations – boo.
Overall it isn’t actually that much of a pain, so I don’t know why I’m complaining about it. It is just something that slightly tarnishes the code, but I guess I can live with it. After all I did decide to use a bunch of Java frameworks with my Scala code. Why didn’t I just use Scala frameworks? Well, mostly because I’m pretty mad, but I’m not completely insane. I figured switching from Java to Scala was a big enough brain realignment without changing everything else I’m used to using as well.
How do I name my interfaces and the classes that implement my interfaces? Through much research on the internet and my own gut feelings, this is what I reckon:
I never prefix my interfaces with “I”. The value of coding to interfaces is that you can swap out the implementation with minimal hassle. It means that instead of using implementation specific class names in your code, you use interface names instead – right? So, if I’m going to be using interface names everywhere, I don’t want to have to prefix everything with “I”. Coding to interfaces is a best practice, so I don’t need to explicitly state that I am doing it…It should just happen – which makes the “I” prefix redundant.
Furthermore, the “Impl” suffix is also redundant. Yes, indeed, your dilemma isn’t as simple as picking between the two. Firstly, “Impl” doesn’t translate. “Impl” in other languages has no meaning, and yes I’m talking about Polish and Scala. In Polish (according to Google translate), “implementation” is “realizacja” and in Scala, there are no interfaces. The closest thing Scala has to interfaces is traits, which can contain implementation specific code. So really, everything is Scala is an implementation, so why you use “Impl” suffix?
Secondly “Impl” is restrictive. What happens when you want to add another implementation of Foo? You gonna call it “FooImplImpl”? “AnotherFooImpl”? “FooImpl2″? I didn’t think so. Perhaps you were going to just call it “FooImpl” and put it in a different package…
Thirdly “Impl” doesn’t convey any meaning about what the implementation is. You wouldn’t create an “AnimalImpl” would you? You’d create a “Lion” or an “Elephant”. There is almost always something that distinguishes your implementation that you can use in the class name. Even if it is a long name, it doesn’t matter – you’re coding to interfaces (remember?), so you’re rarely going to see that class name.
Lastly, and probably most importantly – you still can’t think of a name? You don’t need an interface. If you really can’t think of a name, your class must be generic enough to not need an interface and you’re probably not going to have any other implementations. Your class methods become the interface contract, and that is that.