Question

I have stumbled upon a really annoying situation: I am using Hibernate & Spring as backend for my app and it seems that in some cases, the entities that are in a relationship with a particular entity are not fetched as normal entity objects from the DB, but as Javassist types. E.g.:

I have the Campaign entity with the following relationships:

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

Upon retrieving the salesAreas connected to this Campaign, I get a list of SalesArea_$$_javassist_56, while for the dealers, I get normal Hibernate entities. Since the client part is based on GWT, we use RequestFactory for retrieving stuff. I initially thought it was a problem with the proxies, locators and so on but I have set a breakpoint in the service where these are retrieved and they are Javassist objects directly after selecting them. It seems that even removing the FetchType.LAZY annotation (although definitely not a desirable solution), the same thing happens. This happened also with other types of relationships, not only @ManyToMany.

We are using GWT 2.3, Spring 3, Hibernate 3.6.3 and JPA 2.0 for annotations.

Any suggestions would be appreciated.

Thanks in advance

Was it helpful?

Solution

As far as I can see the big problem that you're having is not so much the fetch type of your association, but rather that the proxied types don't work well with RequestFactory.

Yes, it could be solved by changing the fetch strategy but that sounds rather like a weak workaround that may break upon weird circumstances.

I don't remember exactly how to solve it, but I did, and as far as I remember there was an extension point in the ServiceLayerDecorator class. Basically there you check if the object you're returning is a Hibernate proxy (check Hibernate and HibernateProxy classes) and then return the non-proxy type instead in ServiceLayerDecorator. (http://code.google.com/p/google-web-toolkit/issues/detail?id=6767)

As for your fetch strategy, I'd largely recommend @BatchSize(N) where N is big (maybe 1000), but this is an independent subject.

Good luck!

OTHER TIPS

If you call to the static method: HibernateProxyHelper.getClassWithoutInitializingProxy(entity); you get the class of the proxied entity and the class itself if it wasn't proxied.

With Hibernate's proxy model and now with it's use of Javassist to help avoid the slower traditional Hibernate run time reflection operations things will never quite be as elegant as the clean, intuitive experience people who use full bytecode enhancement solutions like JDO implementations (eg DataNucleus) enjoy.

Personally I can never see the sense in persisting (pardon the pun) with solutions that cause so many problems and fill the web with questions about broken code that requires strange, unintuitive workarounds but still people do...

However, back to the question: one solution to your problem, if you're using JPA, is to use DataNucleus/JPA which brings many of the benefits of DataNucleus/JDO (clean underlying implementation - no proxies, no Javassist classes etc.,) in a JPA compliant implementation - i.e. you don't need to change your existing source code to start using it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top