У меня есть несколько различных типов пользователей (org.hibernate.usertype.UserType) в системе. В этом вопросе я остановлюсь на том факте, что мы используем Joda time DateTime и его UserType, PersistentDateTime.
Я успешно связал UserType программно с PersistentClass's:
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);
}
}
}
}
Вышеприведенный код работает ... но не для компонентов, которые не являются экземплярами PersistentClass. Я попробовал следующий код для обработки компонентов также ... но он не работает, когда кажется, что он должен.
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);
}
}
}
}
}
Я попытался отследить код гибернации. Кажется, что Hibernate каким-то образом обрабатывает компоненты по-другому, чем PersistentClasses, но я не могу понять, как. Мой код выше, кажется, правильно устанавливает typeName для свойства компонента, но Hibernate никогда не использует PersistentDateTime UserType, когда DateTime используется внутри компонента @Embeddable. Конечно, если я добавлю аннотацию @Type, все будет работать. Я не хочу добавлять эту аннотацию. Я хочу иметь возможность связывать UserType программно для компонентов так же, как PersistentClasses.
Есть идеи?
Спасибо!