Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does retrieving a Hibernate proxy's id initialize the proxy?

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?

like image 639
jbarz Avatar asked Feb 09 '10 23:02

jbarz


People also ask

How does Hibernate proxy work?

Hibernate uses a proxy object to implement lazy loading. When we request to load the Object from the database, and the fetched Object has a reference to another concrete object, Hibernate returns a proxy instead of the concrete associated object.

What is proxy pattern in hibernate?

How hibernate uses proxy pattern: Hibernate uses proxy pattern to lazy load entities. For lazy loaded entity or collection, hibernate defers database hit till any property other than identifier (Property marked with @Id) is accessed. The proxy object which hibernate creates has only identifier value set.

Which method returns proxy object in hibernate?

Explanation: load() method returns proxy object. load() method should be used if it is sure that instance exists.

What is proxy in JPA?

The JPA lazy loading mechanism can either be implemented using Proxies or Bytecode Enhancement so that calls to lazy associations can be intercepted and relationships initialized prior to returning the result back to the caller.


1 Answers

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,

like image 147
Arthur Ronald Avatar answered Oct 16 '22 16:10

Arthur Ronald