Spring Boot/Data & Security/Spring Data JPA — ORM và Database Access
1/2
~22 phútData & Security

Spring Data JPA — ORM và Database Access

Từ Entity mapping đến custom queries. Hiểu N+1 problem và cách fix với fetch strategies.

Entity Mapping

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100)
    private String name;

    @Column(unique = true, nullable = false)
    private String email;

    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
    private List<Order> orders;

    @CreationTimestamp
    private LocalDateTime createdAt;
}

Repository

Spring Data JPA tự generate implementation từ method name:

public interface UserRepository extends JpaRepository<User, Long> {

    // SELECT * FROM users WHERE email = ?
    Optional<User> findByEmail(String email);

    // SELECT * FROM users WHERE name LIKE ?
    List<User> findByNameContaining(String keyword);

    // Custom query
    @Query("SELECT u FROM User u JOIN FETCH u.orders WHERE u.id = :id")
    Optional<User> findByIdWithOrders(@Param("id") Long id);
}

N+1 Problem

// N+1 queries!
List<User> users = userRepository.findAll(); // 1 query
for (User u : users) {
    u.getOrders().size(); // N queries (1 per user)
}

// Fix: JOIN FETCH
@Query("SELECT u FROM User u JOIN FETCH u.orders")
List<User> findAllWithOrders(); // 1 query

Key insight: Default fetch type cho @OneToMany là LAZY — tốt cho performance. Nhưng phải ý thức N+1 problem và dùng JOIN FETCH khi cần.