I have several different UserType's (org.hibernate.usertype.UserType) in the system. For this question I will focus on the fact that we use Joda time DateTime and its UserType, PersistentDateTime.
I have successfully bound the UserType programmatically to PersistentClass's by:
public void customize(Ejb3Configuration config) {
Iterator<PersistentClass> itr = config.getClassMappings();
while(itr.hasNext()) {
PersistentClass persistentClass = itr.next();
for(Iterator<Property> iter = persistentClass.getPropertyIterator(); iter.hasNext();) {
if(property.getType().getReturnedClass().equals(DateTime.class)) {
SimpleValue original = (SimpleValue) property.getValue();
SimpleValue value = new SimpleValue(original.getTable());
value.setTypeName("org.joda.time.contrib.hibernate.PersistentDateTime");
value.setTypeParameters(new Properties());
value.setNullValue(original.getNullValue());
Iterator<Column> colIter = original.getColumnIterator();
while(colIter.hasNext())
value.addColumn(colIter.next());
property.setValue(value);
}
}
}
}
The above code WORKS... but not for Components which are not instances of PersistentClass. I tried the following code to handle Components as well... but it DOESN'T work when it really seems like it should.
public void customize(Ejb3Configuration config) {
Iterator<PersistentClass> itr = config.getClassMappings();
while(itr.hasNext()) {
PersistentClass persistentClass = itr.next();
for(Iterator<Property> iter = persistentClass.getPropertyIterator(); iter.hasNext();) {
Property property = iter.next();
if(property.getType().getReturnedClass().equals(DateTime.class)) {
SimpleValue original = (SimpleValue) property.getValue();
SimpleValue value = new SimpleValue(original.getTable());
value.setTypeName("org.joda.time.contrib.hibernate.PersistentDateTime");
value.setTypeParameters(new Properties());
value.setNullValue(original.getNullValue());
Iterator<Column> colIter = original.getColumnIterator();
while(colIter.hasNext())
value.addColumn(colIter.next());
property.setValue(value);
} else if (property.getValue() instanceof Component) {
Component c = (Component)property.getValue();
for(Iterator<Property> cIt= c.getPropertyIterator(); cIt.hasNext();) {
Property cProperty = cIt.next();
if(cProperty.getType().getReturnedClass().equals(DateTime.class)) {
SimpleValue original = (SimpleValue) cProperty.getValue();
SimpleValue value = new SimpleValue(original.getTable());
value.setTypeName("org.joda.time.contrib.hibernate.PersistentDateTime");
value.setTypeParameters(new Properties());
value.setNullValue(original.getNullValue());
Iterator<Column> colIter = original.getColumnIterator();
while(colIter.hasNext())
value.addColumn(colIter.next());
cProperty.setValue(value);
}
}
}
}
}
I have tried tracing through the hibernate code. It seems like hibernate somehow handles Components differently than PersistentClasses but I can't seem to figure out how. My code above seems to correctly set the typeName on the component property but hibernate never uses the PersistentDateTime UserType when DateTime is used inside an @Embeddable Component. Of course, if I add the @Type annotation everything works. I don't want to have to add this annotation. I want to be able to bind the UserType programmatically for Components just the same as PersistentClasses.
Any insights?
Thanks!