Positiv! We've successfully implemented this like this:
Mapping:
Code:
<id name="myPk" type="ch.bedag.gba.cap.server.persistence.hibernate.CapiPkType" access="field">
<column name="FBM01" sql-type="systemId" not-null="true"/>
<column name="FBM02" sql-type="id" not-null="true"/>
<generator class="ch.bedag.gba.cap.server.persistence.hibernate.CapiIdentifierGenerator"/>
</id>
The user type:
Code:
public class CapiPkType implements CompositeUserType {
private static final ch.bedag.gba.common.logging.CapiLogger LOG = ch.bedag.gba.common.logging.CapiLoggerFactory
.getLog(CapiPkType.class);
private static final String[] PROPERTY_NAMES = {"systemId", "id"};
private static final Type[] PROPERTY_TYPES = {Hibernate.LONG, Hibernate.LONG};
public String[] getPropertyNames() {
return PROPERTY_NAMES;
}
public Type[] getPropertyTypes() {
return PROPERTY_TYPES;
}
public Object getPropertyValue(Object component, int property) throws HibernateException {
CapiPK capiPk = (CapiPK)component;
switch (property) {
case 0:
return capiPk.getSystemId().getId();
case 1:
return capiPk.getId();
default:
throw new PersistenceRuntimeException(property+" ist kein gütliger Wert für property (muss 0 oder 1 sein.");
}
}
public void setPropertyValue(Object component, int property, Object value) throws HibernateException {
CapiPK capiPk = (CapiPK)component;
switch (property) {
case 0:
capiPk.setSystemId(new SystemId((Long)value));
case 1:
capiPk.setId((Long)value);
default:
throw new PersistenceRuntimeException(property+" ist kein gütliger Wert für property (muss 0 oder 1 sein.");
}
}
public Class returnedClass() {
return CapiPK.class;
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) return true;
if (x == null || y == null) return false;
return x.equals(y);
}
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
if (LOG.isTraceEnabled()) {
LOG.trace("Names: "+new ReflectionToStringBuilder(names, ToStringStyle.MULTI_LINE_STYLE).toString());
if (owner!=null) {
LOG.trace("Owner: "+owner.getClass().getName());
}
else {
LOG.trace("Owner: null");
}
}
if (rs.getObject(names[0])!=null && rs.getObject(names[1])!=null) {
long systemId = rs.getLong(names[0]);
long id = rs.getLong(names[1]);
return new CapiPK(systemId, id);
}
else {
return null;
}
}
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value==null) {
st.setNull(index, Types.NUMERIC);
st.setNull(index+1, Types.NUMERIC);
}
else {
CapiPK capiPk = (CapiPK)value;
if (capiPk.getSystemId()==null) {
st.setNull(index, Types.NUMERIC);
}
else {
st.setLong(index, capiPk.getSystemId().getId().longValue());
}
if (capiPk.getId()==null) {
st.setNull(index+1, Types.NUMERIC);
}
else {
st.setLong(index+1, capiPk.getId().longValue());
}
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException {
return (Serializable)value;
}
public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException {
return cached;
}
}
The generator:
Code:
public class CapiIdentifierGenerator implements IdentifierGenerator {
public CapiIdentifierGenerator() {
}
public Serializable generate(SessionImplementor session, Object object) {
// your implementation
}
}
HTH
Ernst