7

I know this question was asked several times but I couldn't find a clear example and answer about this topic(I also tried other possible solutions).

I am using Spring JPA and Hibernate and trying to make a lazy fetch for a OneToONe relation. I have 2 simple Entity classes, one Repository class and using h2 database to lazy load an entity. I tried build time bytecode instrumentation to achive this and these are my classes.

Class A

@Entity
public class A {

    private String name;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(optional = false, fetch = FetchType.LAZY, mappedBy = "a")
    @LazyToOne(LazyToOneOption.NO_PROXY)
    private B b;
}

Class B

@Entity
public class B {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "A_ID")
    private A a;
}

Repository

public interface ARepository extends JpaRepository<A, Long> {
    A findByName(String name);
}

pom.xml bytecode enhancer

<plugin>
    <groupId>org.hibernate.orm.tooling</groupId>
    <artifactId>hibernate-enhance-maven-plugin</artifactId>
    <version>${hibernate.version}</version>
    <executions>
        <execution>
            <configuration>
                <failOnError>true</failOnError>
                <enableLazyInitialization>true</enableLazyInitialization>
            </configuration>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
</plugin>

and lastly initdata.sql for h2 database

insert into a (name, id) values ('a', 1);
insert into b (a_id, id) values (1, 1);

When I call findByName() method in a test class it still executes 2 queries for A and B. How can I lazy fetch B class ? Thanks in advance.

drowny
  • 1,897
  • 7
  • 18

2 Answers2

0

In this tutorial has answer on your qustions

That’s because Hibernate needs to know if it shall initialize the manuscript attribute with null or a proxy class. It can only find that out, by querying the manuscript table to find a record that references this Book entity. The Hibernate team decided that if they have to query the manuscript table anyways, it’s best to fetch the associated entity eagerly.

-1

As I know it is imposible to avoid 2 queries, because Hibernate needs to know what should be inserted in your "one to one field" - proxy or null. Proxy is inserted to your object if theres is related record in secondary table, NULL if there isn't any records. So hibernate execute second query to make a check. Insted "one to one" you can use "many to one"

  • I read some articles about build time bytecode instrumentation and most of the people says that it is possible. I think I missed something in my code structure, but thanks for your answer. – Alperen Üretmen Sep 10 '18 at 14:51