Finally got it. Gavins posts above were the correct pointer, just a little too brief to make it too easy.
Anyway, for anyone hitting the same problem as I did, you do have to create a custom type as per the wiki article. Here are the ones I created with at least some of the code bugs corrected from the article...
Code:
package com.myco.hibernate.types;
import java.io.Serializable;
import java.util.Arrays;
public final class Bytes implements Serializable {
private final byte[] _bytes;
public Bytes(byte[] bytes) {
_bytes = bytes;
}
public boolean equals(Object other) {
if (other == null || !(other instanceof Bytes)) {
return false;
}
return Arrays.equals(((Bytes) other)._bytes, _bytes);
}
public byte[] getBytes() {
byte[] dest = new byte[_bytes.length];
System.arraycopy(_bytes, 0, dest, 0, _bytes.length);
return dest;
}
public String toString() {
return _bytes.toString();
}
}
Code:
package com.myco.hibernate.types;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.UserType;
public class BytesType implements UserType {
private static final int[] SQL_TYPES = new int[] { Types.VARBINARY };
public Object deepCopy(Object value) {
return value;
}
public boolean equals(Object x, Object y) {
return (x == y) || (x != null && y != null && x.equals(y));
}
public boolean isMutable() {
return false;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
byte[] bytes = rs.getBytes(names[0]);
if (rs.wasNull())
return null;
return new Bytes(bytes);
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARBINARY);
}
else {
st.setBytes(index, ((Bytes) value).getBytes());
}
}
public Class returnedClass() {
return Bytes.class;
}
public int[] sqlTypes() {
return SQL_TYPES;
}
}
Code:
package com.myco.hibernate.types;
import java.io.Serializable;
import java.sql.SQLException;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.id.IdentifierGenerator;
import net.sf.hibernate.id.UUIDStringGenerator;
public class BytesGenerator implements IdentifierGenerator {
private IdentifierGenerator uuid = new UUIDStringGenerator();
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
try {
return new Bytes(((String) uuid.generate(session, object)).getBytes());
}
catch (SQLException e) {
throw new HibernateException("SQL Exception caught", e);
}
}
}
The hbm.xml file is then changed as follows...
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="com.myco.myapp.hibernate.Tbpperson"
schema="MYAPP"
table="TBPPERSON"
>
<id
name="personId"
type="com.myco.hibernate.types.BytesType"
column="PERSON_ID"
>
<generator class="com.landg.bpa.hibernate.types.BytesGenerator" />
</id>
<property
name="surname"
type="java.lang.String"
column="SURNAME"
not-null="true"
length="40"
/>
<property
name="firstForename"
type="java.lang.String"
column="FIRST_FORENAME"
length="18"
/>
...etc
<!-- associations -->
</class>
</hibernate-mapping>
and finally the java file....
Code:
package com.myco.myapp.hibernate;
import java.io.Serializable;
import java.util.Date;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import com.myco.hibernate.types.Bytes;
/** @author Hibernate CodeGenerator */
public class Tbpperson implements Serializable {
/** identifier field */
private Bytes personId;
/** persistent field */
private String surname;
/** nullable persistent field */
private String firstForename;
...etc
}
Note: You have to change ALL the files (generated by Middlegen in my case) to use Bytes instead of byte[] for the ID column.
Hope this is of use to someone out there.
Chris
P.S I got the Eclipse plugin working in the end so I could debug it, which is how I understood why I needed to do the above.
P.P.S I couldn't get Hibernator 0.9.6 working in Eclipse 3m6, the APIs have changed. It works with 3m3 fine though.