6

我偶然发现了一个非常烦人的情况:我使用 Hibernate 和 Spring 作为我的应用程序的后端,似乎在某些情况下,与特定实体有关系的实体没有从数据库中作为普通实体对象获取,但作为 Javassist 类型。例如:

我有具有以下关系的 Campaign 实体:

@Entity
@Table(name = "campaign")
public class Campaign implements Serializable {
  [..]
  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = {
        "campaign_id", "dealer_id" }), name = "campaign_has_dealer", joinColumns = { @JoinColumn(name = "campaign_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "dealer_id", nullable = false) })
  private List<Dealer> dealers = new ArrayList<Dealer>();

@ManyToMany
// (fetch = FetchType.LAZY)
@JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = {
        "campaign_id", "sales_area_id" }), name = "campaign_has_sales_area", joinColumns = { @JoinColumn(name = "campaign_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "sales_area_id", nullable = false) })
private List<SalesArea> salesAreas = new ArrayList<SalesArea>();
}

检索到与此活动相关的 salesAreas 后,我得到了 SalesArea_$$_javassist_56 的列表,而对于经销商,我得到了普通的 Hibernate 实体。由于客户端部分基于 GWT,我们使用 RequestFactory 来检索内容。我最初认为这是代理、定位器等的问题,但我在服务中设置了一个断点,这些断点在其中被检索,并且它们在选择它们后直接是 Javassist 对象。似乎即使删除 FetchType.LAZY 注释(尽管绝对不是理想的解决方案),也会发生同样的事情。这也发生在其他类型的关系中,不仅仅是@ManyToMany。

我们使用 GWT 2.3、Spring 3、Hibernate 3.6.3 和 JPA 2.0 进行注释。

任何建议,将不胜感激。

提前致谢

4

3 回答 3

4

据我所知,您遇到的最大问题不是关联的获取类型,而是代理类型不适用于 RequestFactory。

是的,它可以通过改变 fetch 策略来解决,但这听起来像是一个很弱的解决方法,可能会在奇怪的情况下中断。

我不记得究竟是如何解决它的,但我做到了,据我所知,ServiceLayerDecorator 类中有一个扩展点。基本上在那里你检查你返回的对象是否是一个 Hibernate 代理(检查 Hibernate 和 HibernateProxy 类),然后在 ServiceLayerDecorator 中返回非代理类型。(http://code.google.com/p/google-web-toolkit/issues/detail?id=6767

至于您的获取策略,我主要推荐 @BatchSize(N) 其中 N 很大(可能是 1000),但这是一个独立的主题。

祝你好运!

于 2011-12-08T05:25:23.523 回答
1

如果调用静态方法: HibernateProxyHelper.getClassWithoutInitializingProxy(entity); 如果没有代理,您将获得代理实体的类和类本身。

于 2014-02-18T13:18:45.513 回答
0

使用 Hibernate 的代理模型,现在使用 Javassist 来帮助避免较慢的传统 Hibernate 运行时反射操作,事情永远不会像使用 JDO 实现(例如 DataNucleus)等完整字节码增强解决方案的人所享受的干净、直观的体验那样优雅.

就我个人而言,我永远看不到坚持(请原谅双关语)解决方案的意义,这些解决方案会导致如此多的问题,并在网络上充斥着关于需要奇怪、不直观的解决方法的损坏代码的问题,但人们仍然这样做......

但是,回到问题:如果您使用 JPA,解决问题的一种方法是使用 DataNucleus/JPA,它带来了 DataNucleus/JDO 的许多好处(干净的底层实现 - 没有代理,没有 Javassist 类等, ) 在符合 JPA 的实现中 - 即您无需更改现有源代码即可开始使用它。

于 2012-10-11T07:02:34.717 回答