Δευτέρα 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:










-------------------------- 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 methods.

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

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

What may be missing, or could get better?