Вопрос

У меня есть класс Hibernate, который по сути является просто оболочкой для множества коллекций.

Таким образом, класс представляет собой (сильно упрощенный / псевдо) что-то вроде:

@Entity  
public class MyClass {

  @OneToMany  
  Map1

  @OneToMany  
  Map2

  @OneToMany   
  Map3

  AddToMap1();  
  AddToMap2();  
  AddToMap3();  
  RemoveFromMap1();  
  RemoveFromMap2();  
  RemoveFromMap3();  
  DoWhateverWithMap1();  
  DoWhateverWithMap2();  
  DoWhateverWithMap3();  

}

и т.д.Затем каждая из этих карт имеет несколько методов, связанных с ней (добавление / удаление / опрос / и т.д.).

Как вы можете себе представить, к тому времени, когда я добавил 10-ю коллекцию или около того, класс стал немного смехотворного размера.

То, что я хотел бы сделать, это что-то вроде:

 
@Entity  
public class MyClass {

  ClassWrappingMap1;

  ClassWrappingMap2;

  ClassWrappingMap3;
}

Со всеми различными методами, включенными в эти классы:

public class ClassWrappingMap1 {

  @OneToMany
  Map

  AddToMap();  
  RemoveFromMap();  
  DoWhateverWithMap();  

}

Я подумал, что, возможно, я мог бы использовать @Embedded для этого, но я, похоже, не могу заставить его работать (Hibernate просто даже не пытается сохранить Map внутри wrapperClass).

Кто-нибудь когда-нибудь делал что-то подобное раньше?Какие-нибудь намеки?

Большое спасибо,
Нед

Это было полезно?

Решение

Руководство по переходу в спящий режим для аннотаций государства , следующие:

Несмотря на то, что спецификация EJB3 не поддерживает Hibernate Annotations, она позволяет использовать аннотации ассоциаций в встраиваемом объекте (например, @*ToOne или @*ToMany).Чтобы переопределить ассоциативные столбцы, вы можете использовать @AssociationOverride.

Таким образом, ваш подход к упаковке должен сработать.


Прежде всего, вы должны проверить все файлы журналов и т.д. На наличие любых связанных с ними ошибок.

Вы могли бы попробовать что-то вроде этого:

  • В вашем мастер - классе (MyClass )
@Entity  
public class MyClass {

  @Embedded
  ClassWrappingMap1 map1;
}
  • И в вашем классе упаковки
@Embeddable
public class ClassWrappingMap1 {

  @OneToMany
  Map map1;

}

Обратите внимание , что ClassWrappingMap1 использование @Embeddable аннотация.Однако, согласно документам, аннотация @Embeddable не должна быть необходима, она должна быть установлена по умолчанию при использовании аннотации @Embedded .

Убедитесь, что каждый класс ClassWrappingMap сопоставляет разные столбцы в базе данных.Также классы ClassWrappingMap не должны иметь первичного ключа (@Id или @EmbeddedId столбцы).

Другие советы

Хотя я не знаю стратегии по умолчанию при использовании класса-оболочки, вы могли бы использовать перехватчик гибернации для инициализации вашей оболочки путем переопределения Загрузка способ.Что - то вроде

public class WrapperInterceptor extends EmptyInterceptor {

    private Session session;

    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        if (entity instanceof MyClass) {
             MyClass myClass = (MyClass) entity;

             Query query = session.createQuery(<QUERY_TO_RETRIEVE_WRAPPED_ENTITY_GOES_HERE>);

             WrappedEntity wrappedEntity = query.list().get(0);

             myClass.setWrapperClass(new WrapperClass(wrappedEntity));
        }
    }

    public void setSession(Session session) {
        this.session = session;
    }
}

Заботится о следующем:

Клиент, использующий этот перехватчик, должен установить свойство Session

Итак, ваш код выглядит следующим образом

WrapperInterceptor interceptor = new WrapperInterceptor();

Session session = sessionFactory().openSession(interceptor);

Transaction tx = session.beginTransaction();

interceptor.setSession(session);

MyClass myClass = (MyClass) session.get(newItem, myClassId); // Triggers onLoad event

tx.commit();
session.close();

Или используйте Spring AOP для выполнения той же задачи.Видишь Дизайн, ориентированный на домен, с использованием Spring и Hibernate

Если вы знаете другую стратегию, поделитесь ею с нами.

с уважением,

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top