I have a Hibernate entity Parent
that is joined to another: Child
. In the database I have a column parent.child_id
that has a foreign key constraint on child.id
. Assuming I'm lazily loading, when I load an instance of Parent
I expect to be able to access parent.getChild().getId()
without incurring a lookup on the child
table.
I expected the proxy returned by parent.getChild()
to be able to fulfil a request to Child.getId()
as it has already loaded the child's id from parent.child_id
column. However, I see an additional query on the child
table.
Why is this extra query necessary, and how can I avoid it? In this instance I'm only interested in the foreign key ID, and do not wish to load the whole row.
Classes:
class Parent {
@Id @Column(name = "id", unique = true, nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "child_id")
private Child child;
}
class Child {
@Id @Column(name = "id", unique = true, nullable = false)
private Integer id;
@Column(name = "name")
private String name;
}
Tables:
CREATE TABLE child (
id int PRIMARY KEY,
name varchar(10)
);
CREATE TABLE parent (
id int PRIMARY KEY,
child_id int REFERENCES (child.id)
);
Use @PrimaryKeyJoinColumn and @PrimaryKeyJoinColumns annotations. From Hibernate manual: The @PrimaryKeyJoinColumn annotation does say that the primary key of the entity is used as the foreign key value to the associated entity.
Introduction. In this post, we feature a comprehensive Example on Hibernate Foreign Key. Foreign key refers to single column or group of columns in table that link data present in another table through its primary key. A Foreign key can't exist without its parent key but viceversa is not true.
Hibernate will scan that package for any Java objects annotated with the @Entity annotation. If it finds any, then it will begin the process of looking through that particular Java object to recreate it as a table in your database! Before Hibernate will start it's scan, not only do we need to invoke the sessionFactory.
It's caused by the fact that Child
uses field access (since annotations are placed on fields), therefore Hibernate simply initializes the proxy when you call any of its methods.
If you move annotations to properies, it would work as expected.
Since JPA 2.0 (Hibernate 3.5) you can configure it in fine-grained way:
@Access(AccessType.FIELD) // Default is field access
class Child {
private Integer id;
@Column(name = "name")
private String name;
@Access(AccessType.PROPERTY) // Use property access for id
@Id @Column(name = "id", unique = true, nullable = false)
public Integer getId() { ... }
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With