Total Pageviews

Thursday, July 04, 2013

Referencing a Derby database column with a reserved name using DBUnit

DBUnit is a pretty good tool to achieve reproducible results when unit testing your code. It puts your database in a known state before each test run.
In my case I use JPA with Hibernate as implementation to create the DB schema before each test run. Furthermore I use an embedded in-memory Derby database.

I ran into problems when inserting dbunit datasets into the created schema. A column was named interval which is a reserved word in Derby.

No problem I thought, when escaping the column name (using ' or " ticks) the problem would be solved. Well it turns out to be not that simple :-(

The solution is to set a DBUnit related property/feature to tell DBUnit how to config and use the underlying database. Here is the relevant code snippet

   IDatabaseConnection memDbConnection = new DatabaseDataSourceConnection(  
       (InitialContext) context, DEFAULT_DATASOURCE);  
   DatabaseConfig dbConfig = memDbConnection.getConfig();  
   dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new DefaultDataTypeFactory());  
   dbConfig.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, "\"?\"");  


The line
dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new DefaultDataTypeFactory());

tells DBUnit to use the default data type factory which works well with Derby. You don't have to set this property explicitly when using Derby.

The second line
dbConfig.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, "\"?\"");  

solved my issue. You have to explicitly declare an escape pattern. In my case this was "\"?"".
With default settings DBUnit uses no escape pattern.

Using this solution, a clean insert into the database with a column that uses a reserved name works as expected.

Wednesday, June 26, 2013

Howto create a DB field with a reserved name using Hibernate and JPA

I stumbled upon this problem when I switched from a SQLServer 2008 database to a MySQL database 5.5 using Hibernate in Version 3.6.6 with JPA implementation 2.0.

The goal

Generating a MySQL database schema or updating a database schema automatically using Hibernate's hbm2ddl.auto feature.

The problem

Using SQLServer for a long time everything worked fine. When switching to MySQL the schema generation failed. In particular, one single table was not created and I couldn't find a hint in Hibernate's log statements.

The solution

My persistence.xml file uses the auto update of a database schema using this property

      <property name="hibernate.hbm2ddl.auto" value="update" />

So far so good. Nothing special here.
I changed the Hibernate dialect to use the MySQL dialect (org.hibernate.dialect.MySQLDialect) and when deploying the application it generates the database schema and it should populate the database with default values. When populating starts it immediately fails with the following Hibernate error message:

"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval) values (0, '10', 9, 4, 7, 1)' at line 1"

After a few minutes it came to my mind that the column name "interval" might be a keyword in MySQL. So googling around I found out that I was right. "interval" is a keyword in MySQL (but not in SQLServer).

Ok, reason found. But what is the best way to fix this issue?
Stackoverflow is your friend :-)
Just read this answer from Stackoverflow and you are done.

To summarize shortly:
With Hibernate as JPA 1.0 provider you have to annotate the entity field with enclosing backticks like this:

@Column(name="`interval`")
 
and when using JPA 2.0 the syntax was standardized you have to escape the column name like this

@Column(name="\"interval\"")

This is mentioned in chapter 2.13 (Naming of database objects) of the JPA 2.0 specification:

"It is possible to specify on a per-name basis that a name for a database object is to be inter-
preted as a delimited identifier as follows:
• Using annotations, a name is specified as a delimited identifier by enclosing the name
within double quotes, whereby the inner quotes are escaped, e.g.,
@Table(name="\"customer\"").
• When using XML, a name is specified as a delimited identifier by use of double
quotes, e.g.,
<table name="&quot;customer&quot;"/>"


Using the first (but deprecated) solution you can force Hibernate to quote an identifier in the generated SQL by enclosing the table or column name in backticks in the mapping document. Hibernate will use the correct quotation style for the SQL Dialect. This is usually double quotes, but the SQL Server uses brackets and MySQL uses backticks.

The second solution is the modern and standardized way of forcing your JPA 2.0 and above provider to quote the identifier.

Sunday, June 23, 2013

Lösung für "mit Windows Update kann derzeit nicht nach Updates gesucht werden"

Wer unter einem Windows 7 (64 Bit) die Funktion "Nach Updates suchen" ausführt und obige Fehlermeldung bekommt fängt erstmal an zu googeln.
Das Problem sollte eigentlich relativ einfach zu beheben sein - dachte ich.
Nun, es gibt diverse Antworten zu dem Problem:
Der letzte Eintrag erwähnt auch das Werkzeug winUpdRestore!v28.exe, welches allerdings mit einem Link in SkyDrive ins Leere läuft.
Die FixIt Lösung von Microsoft hat bei mir nicht funktioniert. Viele Blogeinträge erwähnten jedoch die erfolgreiche Behebung des Problems beim Einsatz des Tools winUpdRestore!v28.exe.

Leider ist dieses Tool so gut wie gar nicht im Web aufzutreiben. Ich habe es dann doch auf dieser Webseite gefunden.

Da ich hoffe, dass dieser Blogartikel auch schnell im Google Index auftaucht, gebe ich hier zwei funktionierende Links für diese Datei an:

  1. https://www.dropbox.com/s/n40u1jzphk3bsgs/winUpdRestore!v28.zip
  2. https://dl.dropboxusercontent.com/u/27481342/winUpdRestore!v28.zip
Das Tool ist kein offizielles Microsoft Produkt und Microsoft wird seine Gründe haben, warum das Werkzeug nicht mehr zu bekommen ist. Bei mir hat das Tool aber das Problem behoben.

Wednesday, May 22, 2013

Essential resources when building Android Apps using Maven (and Eclipse)

If you plan to build your Android application on a build server like Jenkins, Hudson, etc ... you should switch from building your project with your IDE (in my case Eclipse) to a build system like Maven or Gradle.

I tried Gradle (using the new Gradle Build export in Eclipse ADT plugin) because the new Android Studio preview release by Google supports Gradle builds, but was totally disappointed by the poor performance of Gradle on my Jenkins CI build server. So I decided to use maven instead and found out about these resources which you have to read and understand:

  1. Maven Android Plugin:
    You need the plugin to build android projects using maven. With Android API 17 the latest stable release 3.5.3 doesn't work. You have to pull the plugin's source from GitHub and build version 3.5.4-SNAPSHOT by yourself.
  2. Android SDK Deployer:
    "Typically artifacts are available in Maven Central, however only the platform versions available in the Android Open Source Project are published to Maven Central. Newer versions of the platform as well as the compatibility package and proprietary extensions like the Google Maps support are not available there and need to be published to your Maven repository, if you want to use them in your Android project.
    The artifacts published to Maven central are available as dependencies under the groupId com.google.android with the artifactId android and android-test.
    The Maven Android SDK Deployer has been created to publish artifacts from the Android SDK into your local repository or repository server when using components that are not available in Central."


    I have taken this from the online book Maven - The Complete Reference by Sonatype.
    With Android API 17 you might run into the same bug like described above. So before building this project you must build version 3.5.4-SNAPSHOT of the Maven Android Plugin
  3. m2e-android:
    In case you use Eclipse, you can use this m2e plugin to add maven support to your Eclipse Android project.

Monday, May 20, 2013

Install Android Tools on Ubuntu 12.04.

Check this blog when you have to install Android SDK on Ubuntu 12.04. It simply works!

Thursday, April 18, 2013

VirtualBox - Let Host-Only mode access the internet

In an earlier post I described networking modes in VirtualBox. Combining those modes you'll get some kind of swiss knife in realizing somehow exotic networking modes in your VMs.
What if you want your VM that is configured for Host-Only mode access the internet?
Port forwarding using NAT is an option. But for me that sounded to complicated. I had the following requirements:
  1. The host should be able to access services like Apache or GlassFish on the guests (the virtual machine)
  2. The guests should be able to access the outside world (intranet/internet)
  3. The guests should be able to talk to each other using fixed IP adresses
  4. The host should be able to talk to the guests using fixed IP adresses
A working solution for these requirements is described in this blog article.

Sunday, March 10, 2013

Using symbolic links under Windows

Since Windows Vista it is possible to use symbolic links just like you know it under Linux/Unix systems.
Warning: You have to use the command line to use this tool ;-)
The syntax is as follows:

 mklink [[/d] | [/h] | [/j]] <Link> <Target>  

Most of the time I use it with the /d option. This lets the link point to a directory.

Sunday, February 17, 2013

Fixing poor performance (lagging) on Samsung Galaxy Nexus GSM (i9250) phones

Woohoo, I can't believe it. My Galaxy Nexus phone is affected by a bug which causes the phone to slow down and to behave very laggy after a while. Some users reported this might happen when they uploaded or downloaded huge files (e.g. movies).
I can't tell whether huge files caused this problem on my Galaxy Nexus, but from one day to another the phone was reacting very slow. It was no longer usable for me. Typing a single character on the keyboard was a pain in the ass ...
I started to google around and found this posting on XDA which saved my phone's life ;-)
If you are experiencing the same behavior on your Galaxy Nexus you might consider following the steps there. But be careful not to HARD BRICK your phone, because your phone must have a special chipset.
My phone was produced in 08/2012 and really has the "suspicious" V3U00M chipset mentioned in the XDA posting. I checked it using the eMMC Brickbug Check app from the play store.
If your phone is not rooted you can't fix the problem. Either you root it now, or you send it to Samsung and let them repair/swap it. It's up to you.
The next thing to do was to run the LagFix (fstrim) free app or paid version. I now use the paid version, because it has a built in scheduler which runs fstrim every night.
The script mentioned in the posting isn't necessary if you use the paid version of LagFix.
After running the LagFix app my phone was reacting as fast as on the day I bought it and it remains fast until now.

Thursday, February 07, 2013

Multi Line Table Cells in Vaadin 6

I had a hard time figuring out how to wrap content in a table cell using Vaadin 6.7.
Content in row headers can be forced to wrap using a simple "<br/>" tag in the string. Unfortunately it isn't that simple with non-header cells.
I found a working solution in this Vaadin forum post.
You simply have to create your own CSS stylesheet definition and add the following code to it:

 .v-table-cell-wrapper {   
  white-space: normal;   
 }  

Tuesday, February 05, 2013

Howto compress and uncompress a Java byte array using JDK Deflater/Inflater

If you ever came across the requirement to store binary data somewhere (e.g. filesystem or database) it might be handy to compress those data.
Besides the common ZIP algorithm Java offers the Deflater and Inflater classes that uses the ZLIB compression library. ZLIB is part of the PNG standard and not protected by any patents.
Here is a small code snippet which shows an utility class that offers two methods to compress and extract a Java byte array.

 package de.qu.compression.demo;  
   
 import java.io.ByteArrayOutputStream;  
 import java.io.File;  
 import java.io.FileInputStream;  
 import java.io.FileOutputStream;  
 import java.io.IOException;  
 import java.io.InputStream;  
 import java.util.List;  
 import java.util.Map;  
 import java.util.zip.DataFormatException;  
 import java.util.zip.Deflater;  
 import java.util.zip.Inflater;  
   
 public class CompressionUtils {  
  private static final Logger LOG = Logger.getLogger(CompressionUtils.class);  
    
    
  public static byte[] compress(byte[] data) throws IOException {  
   Deflater deflater = new Deflater();  
   deflater.setInput(data);  
   
   ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);   
       
   deflater.finish();  
   byte[] buffer = new byte[1024];   
   while (!deflater.finished()) {  
    int count = deflater.deflate(buffer); // returns the generated code... index  
    outputStream.write(buffer, 0, count);   
   }  
   outputStream.close();  
   byte[] output = outputStream.toByteArray();  
   
   deflater.end();

   LOG.debug("Original: " + data.length / 1024 + " Kb");  
   LOG.debug("Compressed: " + output.length / 1024 + " Kb");  
   return output;  
  }  
   
  public static byte[] decompress(byte[] data) throws IOException, DataFormatException {  
   Inflater inflater = new Inflater();   
   inflater.setInput(data);  
   
   ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);  
   byte[] buffer = new byte[1024];  
   while (!inflater.finished()) {  
    int count = inflater.inflate(buffer);  
    outputStream.write(buffer, 0, count);  
   }  
   outputStream.close();  
   byte[] output = outputStream.toByteArray();  
   
   inflater.end();
   
   LOG.debug("Original: " + data.length);  
   LOG.debug("Uncompressed: " + output.length);  
   return output;  
  }  
 }  
   

It is also possible to receive better compression results by calling the method setLevel of the Deflater class and specify the constant Deflater.BEST_COMPRESSION.