Skillversitas

JPA Entity & Repository

Introduction

An entity is a Java class that represents a database table. A repository is an interface that provides methods for CRUD operations on the entity. Learn how to define both in Spring Boot.

@Entity

An annotation that marks a class as a JPA entity (database table).

@Entity
@Table(name = "users")
public class User {

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

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

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

    @Column(nullable = false)
    private String password;

    @Column(name = "created_at")
    private LocalDateTime createdAt;
}

Entity Annotations

Annotation Purpose
@Entity Mark a class as a table
@Table(name) Table name in the database
@Id Mark a field as the primary key
@GeneratedValue Auto-increment ID strategy
@Column Column configuration
@Transient Field not mapped to a column
@Lob For large data (text/blob)

@GeneratedValue Strategies

Strategy Purpose
IDENTITY Database auto-increment
SEQUENCE Uses a database sequence
TABLE Stores the sequence in a separate table
AUTO Lets JPA decide

Extending JpaRepository

JpaRepository<T, ID> is an interface that provides standard CRUD operations.

public interface UserRepository extends JpaRepository<User, Long> {
}

Available methods:

Method Return Purpose
findAll() List<T> Fetch all data
findById(ID id) Optional<T> Fetch by ID
save(T entity) T Save/update data
deleteById(ID id) void Delete by ID
count() long Count the number of rows
existsById(ID id) boolean Check whether data exists
deleteAll() void Delete all data

Auto-Generated Query Methods

Spring Data JPA automatically generates queries from method names.

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);

    // SELECT * FROM users WHERE age > ?
    List<User> findByAgeGreaterThan(int age);

    // SELECT * FROM users WHERE email = ? AND name = ?
    Optional<User> findByEmailAndName(String email, String name);

    // SELECT * FROM users WHERE name LIKE %?% ORDER BY name ASC
    List<User> findByNameContainingOrderByNameAsc(String keyword);

    // SELECT COUNT(*) FROM users WHERE email = ?
    long countByEmail(String email);

    // SELECT * FROM users WHERE email = ? LIMIT 1
    boolean existsByEmail(String email);
}

Repository Pattern

Separate data access from business logic.

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User create(User user) {
        if (userRepository.existsByEmail(user.getEmail())) {
            throw new DuplicateEntryException("Email is already registered");
        }
        return userRepository.save(user);
    }

    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }

    public List<User> findAll() {
        return userRepository.findAll();
    }

    public void delete(Long id) {
        if (!userRepository.existsById(id)) {
            throw new ResourceNotFoundException("User not found");
        }
        userRepository.deleteById(id);
    }
}

Constructor Injection

Spring recommends constructor injection for dependencies.

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

Summary

  • @Entity + @Id define the mapping to the database.
  • JpaRepository provides CRUD without manual implementation.
  • Method names in a repository automatically become queries.

Next chapter: We'll cover CRUD Operations — a complete implementation of create, read, update, and delete operations with a service layer.