我偶然发现了一个非常恼人的情况:我使用Hibernate和Spring作为我的应用程序的后端,似乎在某些情况下,与特定实体建立关系的实体并不是作为普通实体对象从DB中获取的,而是作为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。
我们使用GWT2.3、Spring3、Hibernate 3.6.3和JPA 2.0进行注释。
如有任何建议,我们将不胜感激。
提前感谢
发布于 2011-12-08 13:25:24
据我所知,您遇到的最大问题不是关联的fetch类型,而是代理类型不能很好地与RequestFactory一起工作。
是的,这可以通过改变抓取策略来解决,但这听起来像是一个很弱的变通方法,可能会在奇怪的情况下中断。
我不记得具体是如何解决这个问题的,但我确实做到了,据我所知,在ServiceLayerDecorator类中有一个扩展点。基本上,您需要检查返回的对象是否是Hibernate代理(检查Hibernate和HibernateProxy类),然后在ServiceLayerDecorator中返回非代理类型。(http://code.google.com/p/google-web-toolkit/issues/detail?id=6767)
至于你的抓取策略,我主要推荐@BatchSize(N),其中N很大(可能是1000),但这是一个独立的主题。
祝好运!
发布于 2014-02-18 21:18:46
如果调用静态方法: HibernateProxyHelper.getClassWithoutInitializingProxy(entity);,您将获得被代理的实体的类以及类本身(如果没有被代理)。
发布于 2012-10-11 15:02:35
有了Hibernate的代理模型,现在又使用了Javassist来帮助避免较慢的传统Hibernate运行时反射操作,事情将永远不会像使用全字节码增强解决方案(如JDO实现(例如DataNucleus) )的人所享受的干净、直观的体验那样优雅。
就我个人而言,我永远看不到坚持(请原谅双关语)解决方案的意义,这些解决方案会导致如此多的问题,并在网络上充斥着关于需要奇怪的、非直观的解决办法的破碎代码的问题,但人们仍然会这样做……
然而,回到问题:如果你正在使用JPA,你的问题的一个解决方案是使用DataNucleus/JPA,它在JPA兼容的实现中带来了DataNucleus/JDO (干净的底层实现-没有代理,没有Javassist类等)的许多好处-也就是说,你不需要改变现有的源代码就可以开始使用它。
https://stackoverflow.com/questions/8412334
复制相似问题