Just a small post now, about something I discovered when developing a JPA example project concerning one-to-one relationships and fetching them.
Say you have 2 entities, A and B, which have a bidirectional one-to-one relationship like this:
@Entity
public class A {
...
@OneToOne
private B b;
}
@Entity
public class B {
...
@OneToOne(mappedBy = "b")
private A a;
}
As you may already know, *ToOne relationships are fetched eagerly using JOIN statements by default. But I wanted those relationships fetched lazily, using a separate select. So I changed the code.
@Entity
public class A {
...
@OneToOne(fetch = FetchType.LAZY)
@Fetch(FetchMode.SELECT)
private B b;
}
@Entity
public class B {
...
@OneToOne(mappedBy = "b", optional = true, fetch = FetchType.LAZY)
@Fetch(FetchMode.SELECT)
private A a;
}
I tried to get an A, and it got A without B. Great. Now I tried getting a B. It also eagerly fetched the A (using a separate select as defined). Huh? After a lot of searching, I found out this was a Hibernate limitation, as explained here. Simply put, the fact that the one-to-one relation is an inverse mapped, optional relationship makes it impossible for Hibernate to determine whether the object should be null or a proxy and therefor it needs to fetch it anyways, rendering a proxy to the related object useless. The result is that the fetch parameter does nothing at all.
Lesson learned: Always test, never assume. That, and it pays to read the JBoss wiki on Hibernate related issues.
#1 by Connie Singleton on 2013/01/25 - 16:33
Which ConnnectionProvider are you using? If its not DatasourceConnectionProvider, then it is probably doing connection pooling. This can cause problems in certain environments. Pooling may be disabled for DriverManagerConnectionProvider by setting hibernate.connection.pool_size=0 in hibernate.properties.