Updates from John DiStasio Toggle Comment Threads | Keyboard Shortcuts

  • John DiStasio 11:58 pm on June 21, 2013 Permalink | Reply
    Tags: hibernate, , mysql   

    Comparing times and debugging query problems with MySQL and Hibernate 

    Earlier today I was working on a problem that involved comparing the values of some java.sql.Time members persisted in MySQL 5.5. I had a start time and a stop time (persisted as time fields), and I needed to generate lists of all entities that were “running” (e.g. the current time was between the entity’s start and stop time). This simple problem caused me a lot of aggravation which boiled down to a basic misunderstanding about how certain Hibernate Restrictions worked, but while I was debugging the issue I learned a little bit about to diagnose problems forming a query via Hibernate. I thought it would be good to publish my experience as I had a hard time finding any information addressing my specific issue.

    Comparing Times

    First, the time comparisons. To find active entities (here where state >= 1) whose run time range included the current time, it was as simple as this:

    Time now = new Time(Calendar.getInstance().getTime().getTime());
    
    Criteria c = session.createCriteria(Thing.class)
    	.add(Restrictions.ge("state", 1))
    	.add(Restrictions.le("start", now))
    	.add(Restrictions.ge("stop", now));
    

    Assuming it was 01:00 AM, that would produce a query equivalent to this:

    SELECT    *
    FROM      Thing
    WHERE     state = 1
      AND     start <= '01:00:00'
      AND     stop >= '01:00:00'; 
    

    Now if we if wanted to find idle entities:

    Time now = new Time(Calendar.getInstance().getTime().getTime());
    
    Criteria c = session.createCriteria(Thing.class)
    	.add(Restrictions.ge("state", 1))
    	.add(Restrictions
    		.or(Restrictions.ge("start", now), Restrictions.le("stop", now)));	
    

    You’d get this:

    SELECT    *
    FROM      Thing
    WHERE     state = 1
      AND     (start >= '01:00:00' OR stop <= '01:00:00'); 
    

    Debugging

    After assuming the problem had something to do with how Hibernate was comparing java.sql.Time objects, I took to the Google looking for answers but found nothing useful. I realized it would be helpful to actually see the SQL Hibernate was generating and go from there, but I had no idea how to do that off the top of my head. There are two ways of doing this.

    Have MySQL log queries
    I found it cleaner to have MySQL log the queries itself. My dev box runs Ubuntu 12.04 and has MySQL server installed directly from Ubuntu’s official repos, so it was all set up as a nice Upstart job. MySQL’s reference manual has clear instructions for enabling this logging. It was as simple as modifying a single line in the Upstart script.

    Change this:

    exec /usr/sbin/mysqld

    To this:

    exec /usr/sbin/mysqld --general_log=1 --general_log_file=/var/log/mysql/query.log

    Substituting another log file if you like, of course.

    Have Hibernate log queries
    You can have Hibernate log the queries it generates with a few simple configuration properties. To get nice formatted output, I added the following to my persistence.xml:

    <property name="hibernate.show_sql" value="true"/>
    <property name="hibernate.format_sql" value="true" />

    If you’re a masochist who likes reading mashed together text you can omit the format_sql.

    Advertisements
     
  • John DiStasio 4:57 pm on June 30, 2012 Permalink | Reply
    Tags: activemq,   

    ActiveMQ: Browsing queues with slashes in their names 

    If you use forward slashes in your queue names and have tried to use ActiveMQ’s queue browsing functionality (see http://activemq.apache.org/rss-and-atom.html), you know it doesn’t work. The problem is that it’s re-writing your call to the queue and replacing your slashes with periods. Check out the getQueue method of the QueueBrowseServlet that handles this and you’ll see this:

    uri = uri.replace('/', '.');
    

    There’s no configuration option to get around that – it just bluntly rewrites your URLs to point at queues with periods. Remove that line, recompile the activemq-web jar, and you’ll be able to browse /your/previously/unbrowsable/queue easily!

     
  • John DiStasio 7:30 pm on June 10, 2012 Permalink | Reply
    Tags: opensuse, ruby   

    Installing Ruby 1.9.3 on openSUSE 12.1 – openssl, zlib and other problems 

    I recently decided to expand my skill set by learning Ruby and Rails. I decided upon using JRuby, as I’ve read that it runs faster than regular Ruby, and I’m attracted to the JVM as a programming platform. Initially, that worked great. Installation was as easy as untaring the download, and it comes with everything I needed – gem, rake, and a whole bunch of other tools I was unfamiliar with.

    Unfortunately the overhead of starting up the JVM each time became apparent quickly. It isn’t a massive delay, but it’s noticeable. Waiting a second or three to see puts "Hello, world!" run is not conducive to experimenting quickly and learning. I decided to install regular C Ruby on my computer, and leave JRuby for when I have something workable to publish.

    At this point in time, openSUSE only officially packages Ruby 1.8.7, and Rails 3 needs Ruby 1.9+, so I had to look elsewhere. I found Ruby 1.9.3 in a devel repo, but installing it from there through Yast broke my gVim install. I considering giving RVM a try, but ultimately decided to attempt to compile it myself.

    After downloading Ruby, I tried to compile it and came out with a working Ruby install. I noticed some error pop up while running make, however:

    configuring -test-/win32/dln
    Failed to configure -test-/win32/dln. It will not be installed.

    Ok, I really don’t think I need that.

    configuring curses
    Failed to configure curses. It will not be installed.

    I don’t see myself ever using that, but I guess it’d be nice to have. Whatever.

    configuring openssl
    Failed to configure openssl. It will not be installed.

    That seems pretty important. I should fix that.

    Overall, these are the messages it gave me:

    Failed to configure -test-/win32/dln. It will not be installed.
    Failed to configure curses. It will not be installed.
    Failed to configure dbm. It will not be installed.
    Failed to configure dl/win32. It will not be installed.
    ffi.h is missing. Please install libffi.
    Failed to configure fiddle. It will not be installed.
    Failed to configure gdbm. It will not be installed.
    Failed to configure openssl. It will not be installed.
    yaml.h is missing. Please install libyaml.
    Failed to configure psych. It will not be installed.
    Failed to configure readline. It will not be installed.
    Can't find "tk.h".
    Can't find proper Tcl/Tk libraries. So, can't make tcltklib.so which is required by Ruby/Tk.
    Failed to configure tk. It will not be installed.
    Failed to configure win32ole. It will not be installed.
    Failed to configure zlib. It will not be installed.

    Within irb, when I tried to reference these libraries, it predictably threw an error:

    > irb
    irb(main):001:0> require 'curses'
    LoadError: cannot load such file -- curses
    from /usr/local/lib64/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /usr/local/lib64/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from (irb):1
    from /usr/local/bin/irb:12:in `<main>'

    Windows stuff aside, I wanted to have as complete an install as possible on my development box, and some of these libraries (openssl, zlib) seemed really important anyways. After some research, I found a blog post by Seth Ladd that seemed to provide some answers.

    As root:

    # cd /path/to/ruby/source/ext/openssl

    1. ruby extconf.rb

    Which led to:

    === OpenSSL for Ruby configurator ===
    === Checking for system dependent stuff... ===
    checking for t_open() in -lnsl... no
    checking for socket() in -lsocket... no
    checking for assert.h... yes
    === Checking for required stuff... ===
    checking for openssl/ssl.h... no
    === Checking for required stuff failed. ===
    Makefile wasn't created. Fix the errors above.

    So it wasn’t as easy as that. Make didn’t explicitly tell me that I was missing this ssh.h header file like it did with ffi.h and yaml.h, but apparently it’s not here. The other missing items returned similar errors open running their extconf.rb script. I installed libopenssl-devel through Yast (this also installed zlib-devel) and ran extconf.rb once again. This time it spit out a bunch of output and ended with creating Makefile. So then:

    # make

    1. make install

    And the moment of truth:

    > irb
    irb(main):001:0> require 'openssl'
    => true

    It works! Zlib also worked just as well. Here’s the full list of those Ruby components and the packages I had to install to for them:

    openssl – libopenssl-devel
    zlib – zlib-devel
    dbm, gdbm – gdbm-devel
    psych – libyaml-devel
    readline – readline-devel
    fiddle – libffi46-devel
    tk – tcl-devel, tk-devel

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel