Picture this: after we had moved an old app from an old server to a new one, we kept getting „I/O Exception: Broken Pipe“ now and then from our database connections. In the new environment, database lives on a different server than our app (as opposed to the old environment). Is there something wrong with the network?

My suspects turned out right: it’s the firewall between app and database. It drops „unused“ tcp connections after an hour. For some security reasons, this cannot be changed.

As our apps is rather old, some parts of it still do not use a connection pool and so there are db connnections that „linger“ around unused for an hour and are used thereafter – bang, I/O exception.

So watch out for that and use a connection pool. Possibly one that can shrink (i.e. throw away unused connections).

Chapter 8 introduces Criteria Queries. Only QueryTest.java is affected. Besides the usual net.sf.hibernate to org.hibernate package import renaming, net.sf.hibernate.expressions in Hibernate 2 is replaced by org.hibernate.criterion.

Moreover, change the line

  1. Example example = Example.create(new Artist(namePattern, null, null));

to

  1. Artist artist = new Artist();
  2. artist.setName(namePattern);
  3. Example example = Example.create(artist);

because Hibernate 3 has generated no argument constructors only.

Chapter 7 is working in Hibernate 3 (as opposed to chapter 6). The most challanging in this chapter migrationwise are StereoVolumeType.java and SourceMediaType.java . Change the import-package names. The Usertype-stuff is now under the package „org.hibernate.usertype“. It won’t compile, yet as there are some methods missing. For SourceMediaType.java:

  1. public Object replace(Object original, Object target, Object owner)
  2.     throws HibernateException {
  3.  
  4.         return original;
  5.    }
  6.  
  7. public Serializable disassemble(Object value) {
  8.        return (Serializable) deepCopy(value);
  9.  }
  10.  
  11. public Object assemble(Serializable cached,
  12.                            Object owner)
  13.     {
  14.         // Our value type happens to be serializable, so we have an easy out.
  15.         return deepCopy(cached);
  16.     }
  17.  
  18. public int hashCode(Object o) { return o.hashCode(); }

For StereoVolumeType.java:

  1. public Object replace(Object original, Object target,SessionImplementor session,
  2.                       Object owner)
  3.     throws HibernateException {
  4.                    
  5.                    return deepCopy((StereoVolumeType)original);
  6.   }
  7.                
  8. public int hashCode(Object o) { return o.hashCode(); }
  9.  
  10. public Object replace(Object original, Object target, Object owner)
  11.                throws HibernateException {
  12.                    
  13.                    return original;
  14.  }

That’s it.

You can skip the entire chapter 6 if you use Hibernate 3. It is based on the interface PersistenceEnum which already became deprecated in Hibernate 2 as the author points out in the errata. The interface has apparently removed in Hibernate 3.

As in chapter 4, copy the hbm.xml-files and change the DTD-reference. Leave CreateTest.java, QueryTest.java and QueryTest2.java alone – they will still compile. Copy the AlbumTest.java file, change the hibernate-imports and the constructor calls as well as int parameters to Integer.

This should be easy as we have done that before.

In this chapter, we add an Entity called „Artist“ as well as an entity called „Comments“.

Copy both Track.hbm.xml and Artist.hbm.xml from the examples-distribution and remember to change the DTD-reference if necessary.
When using „ant schema„, SAX complained it couldn’t find ${src.root}/com/oreilly/hh/hibernate-mapping-2.0.dtd for Artist.hbm.xml.
That’s strange because it didn’t complain about it in Track.hbm.xml before. However, I place the DTD file in ${src.root}/com/oreilly/hh
and the prepare-target now copies *.dtd file, too.

The code generation is no problem. I has changed CreateTest.java again according to Java-beans coding style.
The package name in QueryTest.java and QueryTest2.java needs to be changed again from „net.sf.hibernate...“ to „org.hibernate...“ and everything works.

So that’s it for chapter 4.

A bug in JSSE 1.0.3 keeps me busy the whole monday – ending up with migrating from JDK1.2.2 to JDK1.4.2 „out of the cold“.

In one of my maintenance project that realize some kind of an online-shop, „we“ use a third-party website for payment. Last friday afternoon they installed a new SSL-certificate. Since then, the shop couldn’t connect to that website with JSSE 1.0.3 (itself running an old setup with JDK1.2.2 and JRun – to be overhauled next month).

Tracing revealed „issuer != subject DN“ – even for JDK1.4.2 . I couldn’t figure out why. I tried to store the certificate in a keystore and cacerts but it wouldn’t work either. So I tried a workaround using a dummy trust manager. It worked for JDK1.4.2 but not for JDK1.2.2.

In the end i figured out the server certificate had something like
O=#0C294A3...
in the subject which JSSE 1.0 cannot parse. So even without evaluating the certificate it didn’t work. I was stuck here.

So we had no choice but to immediately upgrade to JDK1.4.2 since otherwise there was no payment possible. Luckily, it worked great! No problems so far!

If the thirdparty had noticed us about the new certificate, I had detected the problem as early as friday afternoon. But that’s life I guess.

Veröffentlicht in Java | Markiert mit

In chapter 3 (you can read it online) we use the Track table to insert some data and to query data.

We use CreateTest to create and QueryTest to query data. Some simple adaptions are necessary:

  • change package name of hibernate classes to org.hibernate
  • replace the use of the all-attributes-as-parameters-constructor with Java-Bean style use of empty constructors and setters
  • change the type of „volume“ attribute from short to java.lang.Short

Here is the changed part of CreateTest.java:

  1. Track track = new Track();
  2.  track.setTitle("Russian Trance");
  3.  track.setFilePath("vol2/album610/track02.mp3");
  4.  track.setPlayTime(Time.valueOf("00:03:30"));
  5.  track.setAdded(new Date());
  6.  track.setVolume(new Short((short)0));
  7.  session.save(track);
  8.  
  9.  track = new Track();
  10.  track.setTitle("Video Killed the Radio Star");
  11.  track.setFilePath("vol2/album611/track12.mp3");
  12.  track.setPlayTime(Time.valueOf("00:03:49"));
  13.  track.setAdded(new Date());
  14.  track.setVolume(new Short((short)0));
  15.  session.save(track);
  16.  
  17.  track = new Track();
  18.  track.setTitle("Gravity's Angel");
  19.  track.setFilePath("vol2/album175/track03.mp3");
  20.  track.setPlayTime(Time.valueOf("00:06:06"));
  21.  track.setAdded(new Date());
  22.  track.setVolume(new Short((short)0));
  23.  session.save(track);

QueryTest needs only substitution of hibernate package names.

I also created a ant-target called „clean-db“ which deletes the entire schema in order to avoid multiple insertion of the same data as well as an ant-target called „clean“ which simply deletes the „classes“-folder.

  1. <target name="clean-db" description="deletes schema of DB.">
  2.     <delete>
  3.       <fileset dir="${data.dir}">
  4.         <include name="**/*"/>
  5.       </fileset>
  6.     </delete>    
  7.   </target>
  8.  
  9.   <target name="clean" description="clean ${class.root}">
  10.     <delete dir="${class.root}"/>
  11.   </target>

So now you can say

  ant clean-db clean schema codegen ctest qtest

and you get a clean db with a new schema, freshly generated code, test data generation and query test – in one command.