3

我有一个 Hibernate 类,它本质上只是一个围绕大量集合的包装器。

所以这个类(大量简化/伪)类似于:

@实体  
公共类 MyClass {

  @OneToMany  
  地图1

  @OneToMany  
  地图2

  @OneToMany   
  地图3

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

}

等等。这些地图中的每一个都有一些与之相关的方法(添加/删除/询问/等)。

你可以想象,当我添加第 10 个左右的集合时,这个类的规模变得有点荒谬了。

我想做的是类似的事情:

 
@实体  
公共类 MyClass {

  类WrappingMap1;

  类WrappingMap2;

  类WrappingMap3;
}

将所有各种方法都包含在这些类中:

公共类 ClassWrappingMap1 {

  @OneToMany
  地图

  添加地图();  
  RemoveFromMap();  
  DoWhateverWithMap();  

}

我想也许我可以使用@Embedded它,但我似乎无法让它工作(Hibernate 甚至没有尝试将 Map 保留在 wrapperClass 中)。

有没有人做过这样的事情?有什么提示吗?

非常感谢,
内德

4

2 回答 2

2

Hibernate 注释手册说明如下:

虽然 EJB3 规范不支持,但 Hibernate Annotations 允许您在可嵌入对象中使用关联注释(即 @*ToOne 或 @*ToMany)。要覆盖关联列,您可以使用@AssociationOverride。

所以你的包装方法应该有效。


首先,您应该检查所有日志文件等是否有任何相关错误。

你可以尝试这样的事情:

  • 在你的大师班(MyClass)
@实体  
公共类 MyClass {

  @嵌入式
  ClassWrappingMap1 map1;
}
  • 在你的包装课上
@可嵌入
公共类 ClassWrappingMap1 {

  @OneToMany
  地图地图1;

}

注意ClassWrappingMap1使用@Embeddable注解。但是,根据文档,应该不需要 @Embeddable 注释,使用 @Embedded 注释时应该是默认的。

确保每个 ClassWrappingMap 类映射数据库中的不同列。ClassWrappingMap 类也不应该有主键(@Id@EmbeddedId列)。

于 2009-12-12T13:29:58.300 回答
0

虽然我不知道使用包装器类时的默认策略,但您可以使用 Hibernate 拦截器通过覆盖onLoad方法来初始化包装器。就像是

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 的领域驱动设计

如果您知道另一种策略,请与我们分享。

问候,

于 2009-12-12T18:43:47.340 回答