Home > Mobile >  Hibernate: N 1 fix for @OneToOne
Hibernate: N 1 fix for @OneToOne

Time:12-29

I have @OneToOne relationship with classes:

@Entity
@Table(name = "persons", schema = "persons_info")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name",
        nullable = false)
    @JsonProperty("first_name")
    private String firstName;

    @Column(name = "last_name",
        nullable = false)
    @JsonProperty("last_name")
    private String lastName;

    @Basic
    @Column(name = "birth_date", nullable = false)
    private Date birthDate;

    @OneToOne(cascade = CascadeType.ALL,
        orphanRemoval = true)
    @JoinColumn(name = "address_id",
        referencedColumnName = "id")
    private Address address;
    
    // setters, getters, equals...
}

Address:

@Entity
@Table(name = "addresses", schema = "persons_info")
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String city;

    @Column(nullable = false)
    private String street;

    @Column(nullable = false)
    private String house;

    @Column(nullable = false)
    private String flat;

    @JsonIgnore
    @OneToOne(mappedBy = "address")
    private Person person;

    // setters, getters, equals...
}

I have a default JpaRepository for person:

@Repository
public interface PersonRepository
    extends JpaRepository<Person, Long> {
}

And when i calling repository.findAll() i taking n 1 problem:

    Hibernate:
        select
            a1_0.id,
            a1_0.city,
            a1_0.flat,
            a1_0.house,
            p1_0.id,
            p1_0.birth_date,
            p1_0.first_name,
            p1_0.last_name,
            a1_0.street
        from
            persons_info.addresses a1_0
        left join
            persons_info.persons p1_0
                on a1_0.id=p1_0.address_id
        where
            a1_0.id=?
    Hibernate:
        select
            a1_0.id,
            a1_0.city,
            a1_0.flat,
            a1_0.house,
            p1_0.id,
            p1_0.birth_date,
            p1_0.first_name,
            p1_0.last_name,
            a1_0.street
        from
            persons_info.addresses a1_0
        left join
            persons_info.persons p1_0
                on a1_0.id=p1_0.address_id
        where
            a1_0.id=?

How i can fix that? (I want fetching with JOIN like this example: SELECT * FROM persons INNER JOIN address ON person.address_id = address.id)

CodePudding user response:

Solved by adding @Query annotation:

@Repository
public interface PersonRepository
    extends JpaRepository<Person, Long> {
    @Query("""
      SELECT p FROM Person p
        LEFT JOIN FETCH p.address a""")
    public List<Person> findAll();
}

Now that's looks like:

    Hibernate:
        select
            p1_0.id,
            a1_0.id,
            a1_0.city,
            a1_0.flat,
            a1_0.house,
            a1_0.street,
            p1_0.birth_date,
            p1_0.first_name,
            p1_0.last_name
        from
            persons_info.persons p1_0
        left join
            persons_info.addresses a1_0
  • Related