Δευτέρα 2 Δεκεμβρίου 2024

JPA, Hibernate and Spring Data JPA

 

Why Use JPA ORMs?

Benefits of JPA ORMs

  1. 🟢 Simplifies Database Interaction 
    With JPA, developers can interact with the database using Java objects rather than writing SQL queries, making the code more maintainable and developer-friendly.

  2. 🟢 Reduced Boilerplate Code 
    JPA reduces repetitive SQL code, allowing developers to focus on business logic instead of low-level database details.

  3. 🟢 Strong Typing and Security 
    By integrating with Java, JPA enforces strong typing, minimizing runtime errors. Parameterized queries are handled internally, reducing the risk of SQL injection attacks.

  4. 🟢 Community Support 
    JPA is widely adopted and maintained, ensuring updates, bug fixes, and community-driven support.



When JPA ORMs Might Not Be Ideal
  1. 🔴Query Limitations
    Complex queries involving multiple joins, aggregations, or DB-specific operations may be challenging or inefficient with JPA.

  2. 🔴Overkill for Small Applications
    Small projects may not justify the learning curve and configuration overhead of JPA. JdbcTemplate is more preferable.

  3. 🔴Vendor Lock-In
    JPA abstracts database operations but can limit flexibility if specific DB features need to be utilized.

  4. 🔴Non-Optimized Queries
    Automatically generated queries may not always be performance-optimized, leading to potential inefficiencies.



Some key Hibernate Annotations and Features

    SessionFactory: 
- Immutable thread-safe cache of compiled mappings for a DB

    Session: 
- Single thread object, wraps JDBC conn, factory of Transaction

    Transaction: 
- Abtracts the app from JDBC, JTA transaction

    HQL: 
- Generates DB-independent queries using objects (entity names) instead of table names. Example:


    EntityManager: 
- Implements the JPA 2 specification.



  1. @GeneratedValue
    Specifies the generation strategy for primary key values:

    • AUTO: Uses the underlying database's strategy.
    • IDENTITY: Uses the database's auto-increment feature.
    • SEQUENCE: Leverages a database sequence.
    • TABLE: Maintains a separate table to store primary keys. Hibernate gets the Id keys from the DB, stores them in hibernate_sequence table and uses it to calculate next Id.
  2. @OneToMany
    Defines one-to-many relationships between entities.

    • Unidirectional: Only one entity is aware of the relationship.
    • Bidirectional: Both entities are aware of and can navigate the relationship.
    • Cascade options (PERSIST, MERGE, etc.) allow operations to propagate across related entities.
  1. @EmbeddedId / @Embeddable: Use for composite primary keys.

Cache Mechanisms

  1. First-Level Cache

    • Session-scoped, automatically enabled.
    • To bypass the cache for large reads, use JPQL or native SQL queries.

    Manually Clear Cache:

    session.detach(entity); // Detach a specific entity session.clear(); // Clear all entities
  2. Second-Level Cache

    • Application-scoped, supports cache providers like EhCache or Redis.
    • Ideal for large reads that don’t change frequently.





------------------------------- Using JPA Without Spring Data JPA ----------------------------


For projects not leveraging Spring Data JPA, the JPA's EntityManager API is the core tool for database operations.

EntityManager Highlights

  • Transactions: You must explicitly manage transactions, while with Spring Data JPA it happens behind the scenes
  • Query Language: Supports both JPQL (object-oriented) and native SQL.

Example Configuration (Hibernate + Spring Boot)

Include the spring-boot-starter-data-jpa dependency, then configure application.properties:






spring.datasource.url=jdbc:mysql://localhost:3306/my_database spring.datasource.username=root spring.datasource.password=secret spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.show-sql=true



Service using EntityManager and @Transactional:



  • With JPA, Spring automatically manages the persistence context (e.g., EntityManager) through dependency injection.
  • Here, the container injects the EntityManager in our enterprise components.
    In other words, the container creates the EntityManager from the EntityManagerFactory.
  • EntityManager instances are not thread-safe!
    Meaning all instances could interfere with the managed entities, causing issues.

    Solution:
    Use container-managed EntityManager (like above). Each thread will have its own EntityManager instance with own managed entities set copy. That prevents concurrent issues in persistence context level, like dirty reads or lost updates. Of course, we have to manage concurrency issues in DB level, with e.g. optimistic locking when having @Version, etc.
  • @Transactional provides declarative transaction management.









-------------------------- Spring Data JPA: Simplifying ORM Further -------------------------


Spring Data JPA abstracts away boilerplate repository code and simplifies transaction management.

Core Features

  1. Repositories
    Use predefined repository interfaces like CrudRepository, JpaRepository, and PagingAndSortingRepository to add functionality effortlessly:

    • CrudRepository: Basic CRUD operations.
    • JpaRepository: Adds advanced features like flushing persistence contexts and batch deletes.
    • PagingAndSortingRepository: Supports paging and sorting queries.
  2. Finder Methods
    Leverage naming conventions to create query methods, e.g.

    List<User> findTop3ByNameOrSurnameContainsOrderByName(String searchTerm);

Example Configuration (Spring Data JPA)

Configure repositories by extending one of the predefined interfaces:

@Repository public interface UserRepository extends JpaRepository<User, Long> { List<User> findByLastName(String lastName); }


How do Repositories work

Auto-implemented by Spring Data engine. At runtime, concrete class is created using proxies
and reflection. A proxy intercepts calls to @Repository class and then route mostly
to SimpleJpaRepository which has defined query methods from reflection.

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

What may be missing, or could get better?