# Native Queries converted to N+1 queries in Hibernate 5.6.15

**URL:** <https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113>\
**Category:** Hibernate ORM\
**Created:** [August 9, 2024, 10:33pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113 "2024-08-09T22:33:08Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_A\_Espinal\_A](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/john_a_espinal_a/32/3412_2.png) [@John\_A\_Espinal\_A](https://discourse.hibernate.org/u/John_A_Espinal_A)\
**Post date:** [August 9, 2024, 10:33pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/1 "2024-08-09T22:33:08Z")

</div>

Guys, when executing a repository with a native query

```auto
@Query(value = "select cc.id, cc.name, ccp.itu from common.countries cc 
LEFT JOIN common.countriesphone ccp on cc.id=ccp.id;"
            , nativeQuery = true)
    public List<Countries> findAllCountriesNativeQuery();

```

the native query is converted to more than 200 queries. One query per country.

As I have two classes Country (Parent Class), and Countryphone (Child Class) I have assured that @ManyToOne in child class is Lazy.

But anyway I am having 20 Seconds of time response when sending the native query, compared to 221 milliseconds when I send the JPQL query.

I really appreciate any suggestion on what I have wrong. Having queries which take 20 seconds when they suppose to take 200 milliseconds has become a major problem for us.

I have recorded the behavior here: [https://vimeo.com/996850300/086679f9ba?share=copy](https://vimeo.com/996850300/086679f9ba?share=copy)

I have these two simple clases. Logs below.

Country

```auto
@Entity
@Table(name = "countries")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Countries {

//	private static final long serialVersionUID = -5594930455475309563L;
	
	@Id
    private Integer id;

    @Column(length = 1, name = "name")
    private String name;

    @OneToMany(mappedBy="countries", fetch = FetchType.EAGER)
    @JsonManagedReference
    private List<Countriesphone> countriesphone;
    
}

```

Countryphone

```auto
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(name = "countriesphone")
@IdClass(CountriesphonePK.class)
public class Countriesphone {

//	private static final long serialVersionUID = -5594930455475309563L;
	@Id
    @JsonIgnore
    private Integer id;

    @Id
	private Integer itu;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id", referencedColumnName = "id",insertable=false,updatable =false)
    @JsonBackReference
    private Countries countries;

}

```

and this repositories:

```auto
@Repository
public interface CountriesRepository extends JpaRepository<Countries, Long> {

    public Iterable<Countries> findAllByOrderByNameAsc();

    @Query("SELECT c FROM Countries c LEFT JOIN FETCH c.countriesphone")
    List<Countries> findAllCountriesJPQL();

    @Query(value = "select cc.id, cc.name, ccp.itu from common.countries cc LEFT JOIN common.countriesphone ccp on cc.id=ccp.id;"
            , nativeQuery = true)
    public List<Countries> findAllCountriesNativeQuery();

}

```

Log using Native query:

```auto
Hibernate:
    /* dynamic native SQL query */ select
        *
    from
        common.countries cc
    LEFT JOIN
        common.countriesphone ccp
            on cc.id=ccp.id;
Hibernate:
    select
        countriesp0_.id as id2_1_0_,
        countriesp0_.itu as itu1_1_0_,
        countriesp0_.itu as itu1_1_1_,
        countriesp0_.id as id2_1_1_
    from
        countriesphone countriesp0_
    where
        countriesp0_.id=?
Hibernate:
    select
        countriesp0_.id as id2_1_0_,
        countriesp0_.itu as itu1_1_0_,
        countriesp0_.itu as itu1_1_1_,
        countriesp0_.id as id2_1_1_
    from
        countriesphone countriesp0_
    where
        countriesp0_.id=?
Hibernate:
    select
        countriesp0_.id as id2_1_0_,
        countriesp0_.itu as itu1_1_0_,
        countriesp0_.itu as itu1_1_1_,
        countriesp0_.id as id2_1_1_
    from
        countriesphone countriesp0_
    where
        countriesp0_.id=?
200. more identical queries.

```

Log using JPQL query. (Working as expected). 221 milliseconds. We do not want to switch from sql to JPQL because we have more 500 sql queries tested and ready to use. So we need to use those.

```auto
/* SELECT
        c 
    FROM
        Countries c 
    LEFT JOIN
        FETCH c.countriesphone */ select
            countries0_.id as id1_0_0_,
            countriesp1_.itu as itu1_1_1_,
            countriesp1_.id as id2_1_1_,
            countries0_.name as name2_0_0_,
            countriesp1_.id as id2_1_0__,
            countriesp1_.itu as itu1_1_0__ 
        from
            countries countries0_ 
        left outer join
            countriesphone countriesp1_ 
                on countries0_.id=countriesp1_.id

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 12, 2024, 5:06pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/2 "2024-08-12T17:06:27Z")

</div>

Your `Country#countriesphone` is marked as eager, so Hibernate has to load that collection when loading a `Country` entity. If you want to implement join fetching like Hibernate ORM does in your HQL query, then you will [have to use Hibernate ORM APIs](https://docs.jboss.org/hibernate/orm/6.6/userguide/html_single/Hibernate_User_Guide.html#sql-hibernate-entity-associations-query-one-to-many-join-example).

---

<div class="post-metadata">

**Author:** ![John\_A\_Espinal\_A](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/john_a_espinal_a/32/3412_2.png) [@John\_A\_Espinal\_A](https://discourse.hibernate.org/u/John_A_Espinal_A)\
**Post date:** [August 12, 2024, 6:03pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/3 "2024-08-12T18:03:34Z")

</div>

> [@John\_A\_Espinal\_A](#):
>
> `@ManyToOne(fetch = FetchType.LAZY)`

Many thanks for answering. Where is tagged as EAGER?. I have checked and I see it is tagged as Lazy. Please see above.

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 13, 2024, 12:20pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/4 "2024-08-13T12:20:48Z")

</div>

I don’t know what to tell you. Check the code that you posted.

```
@OneToMany(mappedBy="countries", fetch = FetchType.EAGER)
@JsonManagedReference
private List<Countriesphone> countriesphone;

```

---

<div class="post-metadata">

**Author:** ![John\_A\_Espinal\_A](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/john_a_espinal_a/32/3412_2.png) [@John\_A\_Espinal\_A](https://discourse.hibernate.org/u/John_A_Espinal_A)\
**Post date:** [August 13, 2024, 12:54pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/5 "2024-08-13T12:54:14Z")

</div>

Many thanks. I had totally misunderstood this.

---

<div class="post-metadata">

**Author:** ![John\_A\_Espinal\_A](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/john_a_espinal_a/32/3412_2.png) [@John\_A\_Espinal\_A](https://discourse.hibernate.org/u/John_A_Espinal_A)\
**Post date:** [August 13, 2024, 5:19pm UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/6 "2024-08-13T17:19:06Z")

</div>

I had changed that one to:

@OneToMany(mappedBy=“countries”, fetch = FetchType.LAZY)  
@JsonManagedReference  
private List countriesphone;

It produces one query. But it generates an error.

Hibernate:  
/\* dynamic native SQL query \*/ select  
cc.id,  
cc.name,  
ccp.itu  
from  
common.countries cc  
LEFT JOIN  
common.countriesphone ccp  
on cc.id=ccp.id  
where  
cc.id is not null;  
2024-08-13 10:05:38.196 WARN 91150 — [nio-9087-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: itk.dbcommon.countries.Countries.countriesphone, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: itk.dbcommon.countries.Countries.countriesphone, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]-\>itk.dbcommon.countries.Countries[“countriesphone”])]

Is there anyway that Hibernate could understand a repository with a native query like:

```auto

@Query(value = "select cc.id, cc.name, ccp.itu from common.countries cc LEFT JOIN common.countriesphone ccp on cc.id=ccp.id;"
            , nativeQuery = true)
    public List<Countries> findAllCountriesNativeQuery();

```

with out generating this error?

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 14, 2024, 9:59am UTC](https://discourse.hibernate.org/t/native-queries-converted-to-n-1-queries-in-hibernate-5-6-15/10113/7 "2024-08-14T09:59:22Z")

</div>

Fetching collections with native queries requires you to use Hibernate ORM APIs, like I wrote before.
