Is there a way to avoid N+1 queries when using a unidirectional @ManyToOne relationship in JPA + Hibernate?

Viewed 108

I have the following entities:

DummyA:

@Entity
@Table(name = "dummy_a")
@Data
public class DummyA implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;


@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "dummy_b_name", referencedColumnName = "name", updatable = false, insertable = false)
private DummyB dummyB;
}

DummyB:

@Entity
@Table(name = "dummy_b")
@Data
public class DummyB implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "entity_id")
private Integer id;

@Column(name = "name")
private String name;
}

As it currently stands, any attempt to fetch DummyA objects results in additional queries to fetch DummyB objects as well. This causes unacceptable extra delay due to N+1 queries and also breaks Page objects returned by repository.findAll(specification, pageable), causing incorrect total page counts and element counts to be returned (in my case repository extends JpaRepository). Is there a way to do it such that DummyB objects are lazily loaded or, if that's not possible, so that they're all eagerly loaded in a single query?

Limitations: I'm fairly new to JPA and Hibernate and have been learning how to use them. I've come across the following in a project I'm working on. I don't have the liberty to include new dependencies and my project currently does not allow hibernate bytecode enhancement through @LazyToOne(LazyToOneOption.NO_PROXY).

Things I've tried so far and did not work / did not work as expected:

  1. @ManyToOne(optinoal = false, fetch = FetchType.LAZY)
  2. Tried to see if accessing the dummyB field in dummyA is what caused the N+1 queries by removing dummyB's setter and getter. Still had N+1 queries.
  3. Using @EntityGraph on findAll.
  4. Tried implementing PersistentAttributeInterceptable and using PersistentAttributeInterceptor to solve the problem.

Links to resources I've looked up so far:

  1. @ManyToOne(fetch = FetchType.LAZY) doesn't work on non-primary key referenced column
  2. N+1 query problem with JPA and Hibernate
  3. Hibernate lazy loading for reverse one to one workaround - how does this work?
  4. PersistentAttributeInterceptable
  5. JPA Entity Graph

Any help is greatly appreciated.

0 Answers
Related