You are looking at posts in the category Java.
Posted on August 2nd, 2011 by Reiner.
Categories: Mac OS X, Java.
This will install Tomcat for developer use - i.e. within your user home path, using your login, not as a service:
cd ~/Librarytar xvfz ~/Downloads/apache-tomcat-6.0.32.tar.gzln -s apache-tomcat-6.0.32 TomcatThen:
~/Library/Tomcat/bin/startup.sh~/Library/Tomcat/bin/shutdown.shConfigure at your leasure, e.g. look here for enabling Tomcat Manager Login: http://www.mkyong.com/tomcat/tomcat-default-administrator-password/
Posted on January 13th, 2010 by Reiner.
Categories: Hibernate, Java, Grails, English.
Working on a Grails project that needs to access a legacy database, it proved quite time-consuming to implement optimistic locking in a way that can be handled by Hibernate. Optimistic locking used to be implemented within (legacy) application code and should now be handled by Hibernate completely on its own. For each entity, the legacy schema uses two nullable columns to both trace creation and last updated times as well as to provide optimistic locking capabilities. TS_INSERT holds the Timestamp the entity has been created and TS_UPDATE (initially null) records subsequent mutations to an entity. Just disabling optimistic locking (as well being advertised here) keeps away run time errors but results in an application that cannot meet production quality demands without additional (awkward) application code.
Annotating the TS_UPDATE column with @Version almost did the trick, except it was unable to successfully update entities that had not yet been updated (TS_UPDATE is null). The reason for this behavior is burried within method toStatementString Hibernate Update- and Delete-Code that use TS_UPDATE=? as part of the sql (prepared) statements in order to check for matching old version values. Of course, this condition will always yield false for null values (remember: null = anything including null = null always yields false).
Short of changing Hibernate source code I designed a work-around, that effectively changes the TS_UPDATE=? fragment so that it yields true, even for null values. The work-around replaces the TS_UPDATE=? with COALESCE(TS_UPDATE,{ts ‘1900-01-01 00:00:00′})=COALESCE(?,{ts ‘1900-01-01 00:00:00′}). I use the COALESCE function, because it is specified by Ansi SQL 92 Standard and thus should be implemented by most database vendors.
Hibernate provides a rather sophisticated set of interceptor methods, that will be called (back) at certain life cycle stages. Using the onPrepareStatement event, arbitrary changes can be applied to the sql statements that are then sent to JDBC for execution. This is what my interceptor looks like (note that it looks for and… as the version condition will always be appended to the primary key condition - todo: this still needs to be verified for persisting collections):
package com.company.fw.hibernate.util.centura;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.EmptyInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Fixes a shortcoming within Hibernate: Hibernate cannot handle NULL values
* within optimistic version columns. The where clause will always include
* e.g. TS_UPDATE=?. We'll try to fix this by changing the sql to e.g.
* COALESCE(TS_UPDATE,{ts '1900-01-01 00:00:00'})=COALESCE(?,{ts '1900-01-01 00:00:00'}),
* so that NULL values match.
*/
public class DBcenturaInterceptor extends EmptyInterceptor {
private static final String PS = "(and) (ts_update)=?";
private static final String RS = "$1 COALESCE($2,{ts '1900-01-01 00:00:00'})=COALESCE(?,{ts '1900-01-01 00:00:00'})";
private static final Pattern P = Pattern.compile(PS, Pattern.CASE_INSENSITIVE);
private final static Logger LOG = LoggerFactory.getLogger(DBcenturaInterceptor.class);
public DBcenturaInterceptor() {
super();
LOG.info("new DBcenturaInterceptor()");
}
/**
* @param sql the sql to be prepared
* @return and TS_UPDATE=? replaced by
* and COALESCE(TS_UPDATE,{ts '1900-01-01 00:00:00'})=COALESCE(?,{ts '1900-01-01 00:00:00'})
*/
@Override
public String onPrepareStatement(final String sql) {
final Matcher m = P.matcher(sql);
final String result = m.replaceAll(RS);
if (LOG.isTraceEnabled() && !result.equals(sql)) {
LOG.trace("onPrepareStatement(" + sql + ") = " + result);
}
return result;
}
}
When creating a session, an interceptor can by passed to the Hibernate SessionFactory.openSession(…). As my application is a Grails application, I choose to provide my Interceptor by passing it to the Grails Hibernate session factory, so my interceptor will be used for all and every Hibernate session created within my Grails application. Starting from Grails 1.2, just a single statement is needed within grails-app/conf/spring/resources.groovy:
import com.company.fw.hibernate.util.centura.DBcenturaInterceptor
// Place your Spring DSL code here
beans = {
entityInterceptor(com.company.fw.hibernate.util.centura.DBcenturaInterceptor)
}
For native Spring applications, have a look at Using a Hibernate Interceptor To Set Audit Trail Properties.
That’s all, take care and have fun ![]()
Posted on January 9th, 2010 by Reiner.
Categories: Hibernate, Java, English.
Working on a Grails project that needs to access a legacy database, I’ve used the Hibernate Tools for Eclipse and Ant to create annotated EJB3 entity classes.
As the database model uses some peculiar concepts (e.g. char(1) for booleans), I ‘ve created Hibernate custom types that properly map database types to Java types. The Hibernate Reveng Tool can be configured to map certain database columns to custom types, but it fails to create the @Type annotation that is required for custom user types. And as numerous reverse engineering cycle are about to be executed, I didn’t want to fix the generated sources by hand.
There already exists a bug for this problem, but there has been no attempt to fix it during the past two years
Thus I’ve designed a work-around and documented it at Issue HBX-849 - Tools does not insert @Type in POJOs for user types defined in reveng.xml ![]()
Posted on March 21st, 2009 by Reiner.
Categories: Chrome, Java, English, Computers.
When you google for Google Chrome and Java you’ll find poor souls that are driven to distraction by Chrome insisting that there is no Java 6 Update 10 or later installed.
Maybe, there are no problems on a clean virgin-like system in mint condition, just unwrapped from its packaging. That’s not mine. I’m a Java developer and all sorts of Java VMs tend to pile up. Right now, I’ll need at least two of them: Java 5 and Java 6.
After an hour of agonizing failures, I found a way to have both Java 5 and Java 6 on my PC and still be able to run Java applets within Google Chrome:
Now I have all three of them, Java 5, Java 6 and Chrome running Java 6 applets
It still puzzles me, I had to install Java 6 first and then Java 5. The other way around would not allow Chrome to recognize Java 6, regardless of any changes being applied to Java within Control Panel…