Гибернация: программно связываемые пользовательские типы для компонентов - PullRequest
2 голосов
/ 29 апреля 2010

У меня есть несколько различных типов пользователей (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.

Есть идеи?

Спасибо!

...