获取Javassist类型而不是实际的Hibernate实体类型

时间:2011-12-07 08:31:58

标签: java hibernate spring javassist

我偶然发现了一个非常烦人的情况:我正在使用Hibernate& amp; Spring作为我的应用程序的后端,似乎在某些情况下,与特定实体关系的实体不会从DB获取为普通实体对象,而是作为Javassist类型。 E.g:

我的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>();
}

在检索连接到此Campaign的salesAreas后,我获得了SalesArea _ $$ _ javassist_56的列表,而对于经销商,我获得了正常的Hibernate实体。由于客户端部分基于GWT,我们使用RequestFactory来检索内容。我最初认为这是代理,定位器等问题,但是我在服务中设置了一个断点,在这些断点中检索这些断点,并且在选择它们之后直接将它们作为Javassist对象。看起来即使删除FetchType.LAZY注释(虽然绝对不是理想的解决方案),同样的事情也会发生。这也发生在其他类型的关系中,而不仅仅是@ManyToMany。

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

任何建议将不胜感激。

提前致谢

3 个答案:

答案 0 :(得分:4)

据我所知,你所遇到的最大问题不是你的关联的获取类型,而是代理类型与RequestFactory不能很好地协作。

是的,它可以通过更改获取策略来解决,但这听起来像是一种可能会在奇怪的情况下破解的弱解决方法。

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

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

祝你好运!

答案 1 :(得分:1)

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

答案 2 :(得分:0)

使用Hibernate的代理模型,现在使用Javassist来帮助避免传统的Hibernate运行时反射操作速度变慢,使用完整字节码增强解决方案(如JDO实现)的人们将无法像干净,直观的体验那样优雅(例如DataNucleus)享受。

就我个人而言,我永远看不到坚持(赦免双关语)解决方案的意义,这些解决方案会导致如此多的问题,并在网上填写有关破解代码的问题,这些问题需要奇怪的,不直观的解决方法,但人们仍然会这样做......

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