Hibernate: programmatically bind UserTypes to components
I have several different UserTypes (org.hibernate.usertype.UserType) on the system. In this question I will focus on the fact that we are using the DateTime and its UserType, PersistentDateTime.
I have successfully linked the UserType programmatically to the PersistentClass with:
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 is WORKS ... but not for Components that are not instances of PersistentClass. I tried the following code for handling components ... but it does NOT work when it really feels 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've tried tracking through hibernate code. Hibernate seems to somehow handle components differently than PersistentClasses, but I can't figure out how. My code above seems to set the typeName correctly on the bean property, but hibernate never uses the custom type PersistentDateTime when DateTime is used inside the @Embeddable bean. Of course if I add @Type annotation everything works. I don't want to add this annotation. I want to be able to bind UserType programmatically for Components just like PersistentClasses.
Any ideas?
Thanks!
a source to share
No one has answered this question yet
Check out similar questions: