7.29.2008

Hibernate Bites... (revisited)

An update to this post. Okay, so we have been able to make the caching work with very little changes to our mappings. By moving the cache element from the child entity definition into the collection declaration in the parent entity we have gotten the caching to work.

Finished Exercise #1 for Scala

I've just finished exercise #1 from: knowing.net. Please feel free to critique this code, I am serious about learning Scala and getting introduced to members of the community.

Calculator.scala

package activeactive
class Calculator {
  def main(args:Array[String]): Double = eval(args.toList)
    def eval(args:List[String]): Double = args match {
      case null =>
        throw new IllegalArgumentException(
          "args cannot be null-valued")
      case Nil =>
        throw new IllegalArgumentException(
          "You must provide a function name as the first argument")
      case "sum" :: rest => sum(convertList(rest))
      case "prod" :: rest => product(convertList(rest))
      case "mean" :: rest => mean(convertList(rest))
      case "sqrt" :: rest => sqrt(convertList(rest))
      case _ => throw new IllegalArgumentException(
        "invalid function name. Use 'sum', 'prod', 'mean', or 'sqrt'.")
    }
    def convertList(list: List[String]): List[Double] = list match {
      case Nil => Nil
      case x :: subList => x.toDouble :: convertList(subList)
    }
    def sum(list: List[Double]) =
      (0D :: list) reduceLeft ((x, y) => x+y)
    def product(list: List[Double]) =
      (1D :: list) reduceLeft ((x, y) => x*y)
    def mean(list: List[Double]) = list match {
      case Nil => throw new IllegalArgumentException(
        "The mean function requires at least one operand")
      case _ => sum(list) / list.size
    }
    def sqrt(list: List[Double]) =
      if (sum(list) <= 0)
        throw new IllegalArgumentException(
          "the input values '" + list.toString +
            "' resulted in a sum <= zero.")
      else if (sum(list) == 1D) 1D
      else Math.sqrt(sum(list))
}
EDIT: updated knowing.net link.

7.28.2008

Hibernate Bites...

...us in the butt Our team recently chose to use Hibernate for handling read-only access to data in our configuration and archive databases. Our primary decision for doing this was to use the baked-in caching provided by ehcache. Since then, we have had three major releases, the first two each containing a bit more hibernate than the previous, and the third, our architecture re-design, in which we spread Hibernate into all of the read-only data access classes. Our love affair with Hibernate was deep and passionate. Then disaster struck. During the verification of the installation of our new architecture to the disaster recovery environment, we found that many of our web-service responses were taking much longer than our service-level agreement allowed, significantly longer. One full week later, we have determined that most of the SessionFactory instances which we thought were caching, were in fact not caching. One particular request to our web service caused 43000 queries to be generated from one repeated (x1000) entity retrieval. This problem did not rear its ugly head in the primary environment because the app server and the database are much closer together on the network in the primary environment. The network timing differences were not great between our primary and disaster recovery environments, but when 43000 queries are being issued, each little bit adds up. We diagnosed our problems with a simple jsp that used SessionFactory.getStatistics() to get the collected statistics and then used Statistics.getEntityStatistics(), Statistics.getQueryStatistics(), and Statistics.getSecondLevelCacheStatistics() to display counts for cache misses, entity loads, cache puts, and cache hits. When you have caches defined that are not being used correctly, you will see more misses than puts, or you will see no misses and many puts. To solve our problems, we are looking at modifying some of the basic assumptions we had about how Hibernate does caching. We are removing some of the mappings in which a parent class was created simply to have one single object to retrieve for each id instead of a list of child objects. We are also now making use of the query cache in the situations in which we are using Criteria.list. In the future, we are looking to spread the use of Spring's JdbcTemplate, Select, and Update classes in conjunction with directly using ehcache or a home-grown caching solution. Lesson Learned: Make sure that you are verifying that your SessionFactory instances are actually caching your cacheable entities as early in the project as you can. If you can, make sure that your integration tests are asserting cache statistics, both in the query cache and in the entity cache.

7.27.2008

HelloWorld in Scala with the Eclipse Plug-in

The Eclipse plug-in for Scala makes you jump through two hoops before letting you run your application from the Run... menu:
  1. Your main object must extend Application.
  2. Since main is now overridden, you must use the override keyword on the method definition.
package activeactive
object Main extends Application {
  override def main(args:Array[String]) {
    println("Hello World!")
  }
}

Learning Scala

I attended Stuart Halloway's dynamic language shoot-out presentation at NFJS last night. Ruby, Clojure, and Scala are the three languages in which he spent his time. Stuart claimed that each of these languages were made to run on the JVM in order to piggy-back on the penetration of the JVM in the enterprise. The choice of language you make is mostly unimportant, most of these interesting languages on the JVM provide the same general additions to Java running on the JVM. I intend to learn Scala this year. I feel that Ruby has a lot of penetration in the software development field, but that Scala is the up-and-coming language. I believe that the concepts and idioms in the languages are common enough to allow me to easily learn Ruby next year. My plan of attack for learning Scala:
  1. Install Eclipse 3.4.
  2. Install the Scala plug-in from: http://www.scala-lang.org/tools/eclipse/index.html.
  3. Create a working hello world program.
  4. Complete the exercises from: http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/.
  5. Decide on a personal project for using Scala.
  6. Complete the personal project.
  7. Find a suitable open-source project using Scala.
  8. Learn more about the project's eco-system.
  9. Contribute to the project's mailing list.
  10. Submit patches to the project.
  11. Decide on a work project using Scala.
  12. Complete the work project.
  13. Lather, rinse, repeat.
EDIT: updated knowing.net link.