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

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

@Entity  
public class MyClass {

  @OneToMany  
  Map1

  @OneToMany  
  Map2

  @OneToMany   
  Map3

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

}

ETC。每个映射都有一些与之关联的方法(添加/删除/询问/等)。

正如您可以想象的那样,当我添加第 10 个集合左右时,该类的大小变得有点荒谬。

我想做的是:

 
@Entity  
public class MyClass {

  ClassWrappingMap1;

  ClassWrappingMap2;

  ClassWrappingMap3;
}

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

public class ClassWrappingMap1 {

  @OneToMany
  Map

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

}

我想也许我可以用 @Embedded 为此,但我似乎无法让它工作(Hibernate 根本不尝试将 Map 保留在wrapperClass 中)。

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

非常感谢,
内德

有帮助吗?

解决方案

Hibernate注释手册 规定如下:

虽然 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 列)。

其他提示

虽然使用的包装类时,我不知道一个默认的策略,你可以使用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;
    }
}

负责下列的:

  

使用该拦截器必须设置会话属性的客户端

所以,你的代码看起来像这样一个

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