Java.Hibernate.Medium.When to choose which strategy ?

✅ Short Answer

  • SINGLE_TABLE → best for simple hierarchies with similar subclasses, prioritizing read performance.
  • JOINED → best for normalized schemas when subclasses have many unique fields → prioritizes schema design and data integrity.
  • TABLE_PER_CLASS → best when subclasses are very different and rarely queried polymorphically → but should be used with caution.

🔎 Detailed Explanation

🔹 SINGLE_TABLE
✅ Choose when:

  • You want fast reads (just one table, no joins or unions).
  • Subclasses share most fields → minimizing unused (NULL) columns.
  • Schema simplicity is more important than normalization.
    ❌ Avoid if:
  • Subclasses have many unique fields → leads to lots of NULLs.

🔹 JOINED
✅ Choose when:

  • You want normalized tables → avoids many NULL columns.
  • Subclasses have significant differences in their fields.
  • You care about data integrity and clean schema design.
  • You don’t mind slightly slower reads due to JOINs.
    ❌ Avoid if:
  • You need maximum read performance → JOINs introduce overhead.

🔹 TABLE_PER_CLASS
✅ Choose when:

  • Subclasses are completely unrelated in their fields → e.g., base class used only for a common interface (like abstract base).
  • Polymorphic queries (across subclasses) are rare → since they need slow UNIONs.
    ❌ Avoid if:
  • You frequently query across the entire hierarchy → UNION queries will kill performance.
  • You need clean normalization → base class fields are duplicated in each table.

📊 Decision Table

ScenarioRecommended Strategy
Fastest read performanceSINGLE_TABLE
Few subclass-specific fieldsSINGLE_TABLE
Many subclass-specific fieldsJOINED
Prioritize normalizationJOINED
Subclasses are very different, unrelatedTABLE_PER_CLASS
Rarely query the hierarchy polymorphicallyTABLE_PER_CLASS

📌 Key Takeaways

✅ Use SINGLE_TABLE for performance-critical apps with simple hierarchies.
✅ Use JOINED when you need normalized design and subclasses have many exclusive fields.
✅ Use TABLE_PER_CLASS only when subclasses are radically different and polymorphic queries are rare.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.When to choose which strategy ?

Java.Hibernate.Medium.Explain the TABLE_PER_CLASS strategy.

✅ Short Answer

The TABLE_PER_CLASS strategy maps each concrete subclass in an inheritance hierarchy to its own separate table, each with all fields from the base class + subclass.
There’s no table for the abstract base class.

🔎 Detailed Explanation

🔹 In TABLE_PER_CLASS:

  • Each concrete class (i.e., classes you can instantiate) has its own table.
  • The table contains columns for all inherited fields from the base class + the subclass’s own fields.
  • There is no common parent table — each subclass table is independent.

🔹 When you query the base type (polymorphic query), Hibernate performs a UNION of all subclass tables.

🧑‍💻 Example

Entities:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {
    @Id
    private Long id;
    private String name;
}

@Entity
public class Dog extends Animal {
    private String breed;
}

@Entity
public class Cat extends Animal {
    private boolean likesMilk;
}

Database tables created:

Table: dog
| id | name | breed |

Table: cat
| id | name | likes_milk |

⚠️ There is no animal table, only separate tables for concrete classes.

🔹 How Hibernate Queries with TABLE_PER_CLASS

  • Polymorphic queries like:
SELECT a FROM Animal a

require Hibernate to issue a UNION query combining dog and cat tables, e.g.:

SELECT id, name, breed, NULL AS likes_milk FROM dog
UNION ALL
SELECT id, name, NULL AS breed, likes_milk FROM cat

📊 Advantages & Disadvantages

✅ Pros:

  • Simple tables → each table only has relevant fields → no null columns.
  • Each concrete class is independent → useful if subclasses are totally unrelated in data.

❌ Cons:

  • Polymorphic queries are slow → require UNIONs.
  • Data for shared fields is duplicated across subclass tables → denormalized.
  • Schema changes (e.g., adding a base class field) require changing multiple tables.

📌 Key Takeaways

✅ TABLE_PER_CLASS creates one table per concrete class, no shared base table.
✅ Avoids nulls but causes duplication of base fields → leads to maintenance headaches.
✅ Polymorphic queries can be inefficient due to UNIONs.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.Explain the TABLE_PER_CLASS strategy.

Java.Hibernate.Medium.Explain the JOINED strategy.

✅ Short Answer

The JOINED strategy maps each class in an inheritance hierarchy to its own table, linking them by foreign keys, and represents a more normalized approach compared to SINGLE_TABLE.

🔎 Detailed Explanation

🔹 In JOINED, each entity class — base and subclasses — has its own separate table in the database:

  • The base class table holds columns for base fields + the primary key.
  • Each subclass table holds only the subclass-specific fields + a primary key that joins to the base table’s primary key.

🔹 When you query a subclass, Hibernate joins the subclass table with the base table to build the full entity.

🔹 This strategy avoids having many nullable columns in a single wide table → better normalization.

🧑‍💻 Example

Entities:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Animal {
    @Id
    private Long id;
    private String name;
}

@Entity
public class Dog extends Animal {
    private String breed;
}

@Entity
public class Cat extends Animal {
    private boolean likesMilk;
}

Database tables created:

Table: animal
| id | name |

Table: dog
| id | breed |

Table: cat
| id | likes_milk |

🔹 How Hibernate Loads with JOINED

  • When you query Dog, Hibernate joins animal + dog on their shared primary key (id):
SELECT a.*, d.* FROM animal a
JOIN dog d ON a.id = d.id
WHERE ...

Hibernate assembles the full Dog object from data spread across these tables.

📊 Advantages & Disadvantages

✅ Pros:

  • Better normalized schema → no columns with lots of NULLs.
  • Clean separation of shared vs. subclass-specific data.
  • Good when subclasses are very different or have many exclusive fields.

❌ Cons:

  • Slower queries than SINGLE_TABLE → requires JOINs at runtime.
  • More complex schema → more tables, harder to inspect manually.

📌 Key Takeaways

✅ JOINED strategy maps each class to its own table, with subclass tables joined to the base table via primary keys.
✅ Improves normalization → no wasted NULL columns like SINGLE_TABLE.
✅ Comes with performance cost → requires SQL joins to load subclass instances.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.Explain the JOINED strategy.

Java.Hibernate.Medium.Explain the SINGLE_TABLE strategy.

understanding SINGLE_TABLE is key because it’s the most common (and default) inheritance strategy in JPA/Hibernate. Let’s break it down clearly:

✅ Short Answer

The SINGLE_TABLE strategy stores all entities in an inheritance hierarchy in a single database table, using a discriminator column to distinguish between subclasses.

🔎 Detailed Explanation

🔹 With SINGLE_TABLE, you map an entire class hierarchy (base + subclasses) to one table.
🔹 The table includes columns for all fields declared in the base class and in every subclass.
🔹 Hibernate uses a discriminator column to identify which subclass a row represents:

  • By default, the discriminator column is called DTYPE.
  • You can customize it with @DiscriminatorColumn.

🔹 Since all fields for all subclasses live in one table:
✅ Reading is fastest — no joins or unions required.
❌ Leads to many nullable columns — fields belonging to one subclass will be null for rows of other subclasses.

🧑‍💻 Example

Entities:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "animal_type")
public abstract class Animal {
    @Id
    private Long id;
    private String name;
}

@Entity
public class Dog extends Animal {
    private String breed;
}

@Entity
public class Cat extends Animal {
    private boolean likesMilk;
}

Resulting single table:

idnamebreedlikesMilkanimal_type
1FidoBeagleNULLDog
2WhiskersNULLtrueCat

🔹 How Hibernate Uses Discriminator

  • When loading rows, Hibernate reads animal_type (or DTYPE by default) to decide which subclass (Dog, Cat, etc.) to instantiate.

📊 Advantages & Disadvantages

✅ Pros:

  • Simple schema: only one table.
  • Fast selects — no need for joins or unions.
  • Easy to implement.

❌ Cons:

  • Can result in a wide table with many nulls.
  • Not normalized → bad fit if subclasses are very different in data.

📌 Key Takeaways

✅ SINGLE_TABLE stores the entire hierarchy in one table, with a discriminator column to identify subclasses.
✅ Fastest option → perfect when subclasses are similar or have few unique fields.
✅ Can waste space with many nullable columns if subclasses differ widely.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.Explain the SINGLE_TABLE strategy.

Java.Hibernate.Medium.What is default inheritance strategy ?

✅ Short Answer

The default inheritance strategy in JPA/Hibernate is SINGLE_TABLE.


🔎 Detailed Explanation

  • If you define an inheritance hierarchy with @Inheritance or even without specifying the strategy, JPA assumes:
@Inheritance // equivalent to @Inheritance(strategy = InheritanceType.SINGLE_TABLE)

This means:

  • All classes in the hierarchy share one table in the database.
  • A discriminator column (by default named DTYPE) identifies which subclass each row represents.

If you don’t set @DiscriminatorColumn, JPA auto-generates one named DTYPE.

Example:

@Entity
@Inheritance // same as @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Animal { ... }

@Entity
public class Dog extends Animal { ... }

@Entity
public class Cat extends Animal { ... }

This setup will create a single table (e.g., Animal) with columns for all fields in Animal, Dog, and Cat.

📌 Key Takeaways

✅ If you don’t explicitly specify an inheritance strategy, SINGLE_TABLE is used by default.
✅ Hibernate uses a discriminator column (DTYPE) to track which subclass each row belongs to.
✅ Always choose a strategy explicitly if you want a different mapping → JOINED or TABLE_PER_CLASS.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.What is default inheritance strategy ?

Java.Hibernate.Medium.What inheritance strategies does Hibernate support?

✅ Short Answer

Hibernate supports three main inheritance mapping strategies:
1️⃣ SINGLE_TABLE → all classes in one table.
2️⃣ JOINED → one table per class, joined by foreign keys.
3️⃣ TABLE_PER_CLASS → one table per concrete class.

🔎 Detailed Explanation

🔹 1) SINGLE_TABLE (Single Table Inheritance)

  • All entities in the inheritance hierarchy share a single database table.
  • A discriminator column identifies which subclass each row belongs to.
  • Fastest reads → only one table to query.
  • Drawback: lots of nullable columns → unused columns for some subclasses.

Usage:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")
public abstract class Animal { ... }

@Entity
public class Dog extends Animal { ... }

@Entity
public class Cat extends Animal { ... }

🔹 2) JOINED (Joined Table Inheritance)

  • Each class (including abstract base) has its own table.
  • Subclass tables have foreign keys referencing the base table.
  • Data for an entity is spread across multiple tables → requires JOINs when querying.
  • Reduces null columns; better normalization.

Usage:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Animal { ... }

@Entity
public class Dog extends Animal { ... }

@Entity
public class Cat extends Animal { ... }

🔹 3) TABLE_PER_CLASS (Table per Concrete Class)

  • Each concrete subclass has its own table, with all fields from the base and subclass.
  • No shared base table → base class has no table if it’s abstract.
  • Polymorphic queries across the hierarchy result in UNION queries → can be less efficient.
  • Can cause duplicated columns across tables.

Usage:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Animal { ... }

@Entity
public class Dog extends Animal { ... }

@Entity
public class Cat extends Animal { ... }

📊 Quick Comparison Table

StrategyTables in DBSpeedNull columnsPolymorphic queries
SINGLE_TABLE1 tableFastestMany possibleSimple (one table)
JOINEDOne per class, joinedMediumFewJoins needed
TABLE_PER_CLASSOne per concrete classSlowestNoneUses UNIONs

💡 Choosing a Strategy

✅ Use SINGLE_TABLE for performance-critical, simple hierarchies with few subclasses.
✅ Use JOINED for normalized schemas or hierarchies with many subclass-specific fields.
✅ Use TABLE_PER_CLASS when subclasses are very different, but be cautious of UNION performance.


📌 Key Takeaways

✅ Hibernate supports SINGLE_TABLE, JOINED, and TABLE_PER_CLASS inheritance strategies.
✅ Choose the strategy based on schema design, performance, and polymorphic query needs.
✅ Always use @Inheritance(strategy = …) and optionally @DiscriminatorColumn for SINGLE_TABLE.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.What inheritance strategies does Hibernate support?

Java.Hibernate.Medium.Can we use subqueries in JPQL ?

✅ Short Answer

Yes — JPQL supports subqueries, but only in the WHERE and HAVING clauses, not in the FROM clause.


🔎 Detailed Explanation

🔹 Where you can use subqueries in JPQL
✅ WHERE clause → use a subquery to filter parent entities based on data from another entity.
✅ HAVING clause → use subqueries with aggregates to filter grouped results.

❌ FROM clause → JPQL does not support subqueries in FROM, unlike SQL.


🔹 Example: Subquery in WHERE
Find customers who have orders over $10,000:

String jpql = """
    SELECT c FROM Customer c
    WHERE EXISTS (
        SELECT o FROM Order o
        WHERE o.customer = c AND o.total > 10000
    )
    """;
List<Customer> richCustomers = em.createQuery(jpql, Customer.class).getResultList();

✅ Here, the subquery inside EXISTS filters customers with qualifying orders.

🔹 Example: Subquery with IN
Find products ordered in orders from a specific country:

String jpql = """
    SELECT p FROM Product p
    WHERE p.id IN (
        SELECT oi.product.id FROM OrderItem oi
        WHERE oi.order.customer.country = :country
    )
    """;
List<Product> products = em.createQuery(jpql, Product.class)
                           .setParameter("country", "USA")
                           .getResultList();

📊 Quick Facts about JPQL Subqueries

Supported LocationSupported?Notes
WHERE clause✅ YesMost common use case
HAVING clause✅ YesFor aggregated filters
FROM clause❌ Not allowedJPQL doesn’t support derived tables/subselects in FROM

🔹 What if you need FROM subqueries?

  • You must switch to native SQL → use createNativeQuery() if your query absolutely requires subqueries in the FROM clause.

📌 Key Takeaways

✅ JPQL supports subqueries in WHERE and HAVING → great for filtering based on related or aggregated data.
❌ JPQL does not allow subqueries in the FROM clause.
✅ For FROM subqueries, use native SQL queries.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.Can we use subqueries in JPQL ?

Java.Hibernate.Medium.What’s the difference between fetch joins and normal joins in HQL?

✅ Short Answer

  • A normal join (JOIN, LEFT JOIN) combines tables/entities for filtering or constraints, but does not fetch related entities into your object graph.
  • A fetch join (JOIN FETCH) loads the associated entities eagerly along with the parent in a single query, populating their fields immediately — crucial to avoid the N+1 problem.

🔎 Detailed Explanation

🔹 Normal Joins

  • Used when you want to filter or restrict results based on related entity data.
  • Does not load associated entities into memory → they remain lazily loaded if marked as lazy.
  • Typically returns only the parent entity or fields selected.

Example:

String hql = "SELECT o FROM Order o JOIN o.customer c WHERE c.status = :status";
List<Order> orders = em.createQuery(hql, Order.class)
                       .setParameter("status", "ACTIVE")
                       .getResultList();

✅ This filters orders by customer status.
❌ But o.customer remains uninitialized (lazy) → accessing order.getCustomer() later can still trigger an extra SQL query.

🔹 Fetch Joins

  • Uses JOIN FETCH to tell Hibernate/JPA to load the related entities right away.
  • Fetched entities are fully initialized and attached to the parent.
  • Avoids lazy-loading and solves the N+1 problem.

Example:

String hql = "SELECT o FROM Order o JOIN FETCH o.customer c WHERE c.status = :status";
List<Order> orders = em.createQuery(hql, Order.class)
                       .setParameter("status", "ACTIVE")
                       .getResultList();

✅ Here, each Order comes with its Customer already loaded, even if customer was mapped as lazy.

📊 Quick Comparison Table

FeatureNormal JOINJOIN FETCH
PurposeFiltering/constraintsFetching associations eagerly
Loads child entity?❌ No✅ Yes
Solves N+1?❌ No✅ Yes
ReturnsParent or selected fieldsParent with initialized associations

🔹 Important Notes
✅ Both joins use entity relationships → no SQL ON clauses.
❗ Fetch joins cannot be used in subqueries → only top-level JPQL/HQL.
❗ Fetch joins on collections can cause duplicate parent rows → careful with pagination.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.What’s the difference between fetch joins and normal joins in HQL?

Java.Hibernate.Medium.how JOIN FETCH solves the N+1 problem ?

✅ Short Answer

A JOIN FETCH in JPQL/HQL tells Hibernate to eagerly load the parent and its associated entities in a single SQL query, instead of using separate queries per association.
This eliminates the N+1 problem by reducing the number of queries from (1 + N) to just 1.

🔎 Detailed Explanation

  • Without JOIN FETCH:
    • Query 1: loads all parent entities → e.g., SELECT * FROM orders;.
    • Then for each parent (N times): a separate query to load the associated entity (e.g., customer).
    • Total: 1 + N queries → N+1 problem.
  • With JOIN FETCH:
    • Hibernate generates a single SQL query with an SQL JOIN → retrieves parent + child rows together.
    • It then builds both parent and child entities from this single result set, linking them in memory.

🔹 Example Fixing N+1
Problematic code (N+1):

List<Order> orders = em.createQuery("SELECT o FROM Order o", Order.class).getResultList();
for (Order o : orders) {
    Customer c = o.getCustomer(); // Each call triggers 1 SQL if customer is LAZY
}

Optimized with JOIN FETCH:

String jpql = "SELECT o FROM Order o JOIN FETCH o.customer";
List<Order> orders = em.createQuery(jpql, Order.class).getResultList();

for (Order o : orders) {
    Customer c = o.getCustomer(); // Already loaded — no extra queries!
}

🔹 SQL Generated with JOIN FETCH
Hibernate generates something like:

SELECT o.*, c.* FROM orders o
JOIN customers c ON o.customer_id = c.id

One query → loads orders and their customers together.

🔹 How JOIN FETCH Solves It
✅ Eliminates extra queries → prevents (1 + N) problem.
✅ Loads parent + children immediately, avoiding lazy-loading round trips.
✅ Dramatically improves performance on large datasets.


📌 Key Takeaways

✅ JOIN FETCH merges parent + child loading into one efficient query.
✅ Avoids N+1 by eliminating lazy-loading queries for each parent’s child.
✅ Essential for high-performance ORM applications with related data.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.how JOIN FETCH solves the N+1 problem ?

Java.Hibernate.Medium.What is N+1 problem ?

✅ Short Answer

The N+1 problem happens when an ORM (like Hibernate) executes 1 query to load N parent entities, and then N separate queries (1 per parent) to load their associated child entities → resulting in 1 + N total queries → causing major performance issues.

🔎 Detailed Explanation

  • It usually appears when you load a collection of parent entities and access lazy-loaded associations in a loop.
  • Example scenario:
    • You query 100 Order objects → runs 1 SQL query.
    • Each order has a Customer lazily loaded → accessing order.getCustomer() triggers a separate SELECT per order.
    • Total queries: 1 (parent) + 100 (one per order) = 101 queries.
  • Why it’s bad:
    • Adds massive overhead → floods the database with many small queries.
    • Leads to poor performance, especially over high-latency connections or with large datasets.

🧑‍💻 Concrete Example

// 1 query to get all orders
List<Order> orders = entityManager.createQuery("SELECT o FROM Order o", Order.class)
                                  .getResultList();

for (Order o : orders) {
    // N queries: one per order if customer is lazily loaded
    Customer c = o.getCustomer();
    System.out.println(c.getName());
}

With 500 orders → you end up with 501 queries instead of ideally just 1 or 2!

🔹 N+1 Visualized

1  query → SELECT * FROM orders;
N  queries → SELECT * FROM customer WHERE id = ? (1 per order)

🚑 How to Fix N+1

✅ Use fetch joins (JOIN FETCH) → loads parent + children together in 1 query:

String jpql = "SELECT o FROM Order o JOIN FETCH o.customer";
List<Order> orders = entityManager.createQuery(jpql, Order.class)
                                  .getResultList();

✅ Or configure entity relationships to eagerly fetch when appropriate → but beware: eager loading can lead to loading unnecessary data if you’re not careful.

📌 Key Takeaways

✅ The N+1 problem happens when a single parent query triggers N additional child queries.
✅ It causes excessive SQL traffic, hurting performance on larger datasets.
✅ Solve it with fetch joins or proper fetch strategies.

Posted in Без рубрики | Comments Off on Java.Hibernate.Medium.What is N+1 problem ?