hibernate 休眠:N+1修复@OneToOne

1bqhqjot  于 2022-12-27  发布在  其他
关注(0)|答案(1)|浏览(158)

我与类有@OneToOne关系:

@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...
}

地址:

@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...
}

我为person设置了默认值JpaRepository

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

当我调用repository.findAll()时,我会遇到n+1问题:

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=?

我怎么能解决这个问题?(我想用JOIN取像这个例子:SELECT * FROM persons INNER JOIN address ON person.address_id = address.id

agxfikkp

agxfikkp1#

通过添加@Query注解解决:

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

现在看起来像:

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

相关问题