views:

243

answers:

1

In Hibernate when you retrieve an Entity via a load, if you access that Entity's id accessor it does not initialize the proxy:

Property myProp = (Property) session.load(Property.class, myId);
myProp.getId(); // Doesn't load the proxy
myProp.getDescription();  // Loads the proxy from the database hit

However, I am unclear what the rules are for loading association proxies. I was under the impression that when you retrieve an Entity via a HQL query or Criteria the same rules apply.

Each Property in my code has a Company. The Company is declared as such:

@ManyToOne(fetch = FetchType.LAZY, optional=false)
@JoinColumn(name = "company_id", nullable=false)
private Company company;

However, in my code I'm currently getting N+1 selects when iterating through the Properties because the Company is being loaded when I call Company.getId().

In both the Company and Property object the id field is a Long annotated with @Id.

Is there some other consideration I'm missing in order to prevent the loading of the Company entity?

+2  A: 

Hi,

It does not work as expected simply because of you have to use property access instead of field access.

Instead of

@ManyToOne(fetch=FetchType.LAZY, optional=false)
@JoinColumn(name="COMPANY_ID", nullable=false)
private Company company;

Use

@ManyToOne(fetch=FetchType.LAZY, optional=false)
@JoinColumn(name="COMPANY_ID", nullable=false)
public Company getCompany() {
    return this.company;
}

Takes care you can not use property access and field acces at the same time. So you should choose one approach.

regards,

Arthur Ronald F D Garcia
+1 - more detailed explanation is available here: http://www.catalysts.cc/en/blog/ejb-annotations-hibernate-lazy-loading/
Gennady Shumakher
I see, from reading the article it seems like the right approach is actually to change the Company object so that the annotations are all on the getters. Its more important that the getId() method is annotated rather than getCompany() on Property.
jbarz