Advanced Entity Mapping

Back

Loading concept...

Advanced Entity Mapping in JPA 🏗️

The Building Blocks Story

Imagine you’re building with LEGO blocks. Some blocks are special—they can be parents that share their shape with child blocks. Some blocks are containers that hold smaller pieces inside. And some blocks have magic powers that transform things!

That’s exactly how Advanced Entity Mapping works in JPA. Let’s explore each building block!


1. Entity Inheritance 👨‍👩‍👧‍👦

What is it?

Think of a family tree. Grandpa has certain traits (like brown eyes). Dad inherits those traits. You inherit from Dad!

In JPA, a parent entity can pass its fields to child entities. Just like how all vehicles have wheels, but cars and motorcycles are different!

@Entity
@Inheritance
public class Vehicle {
    @Id
    private Long id;
    private int wheels;
}

@Entity
public class Car extends Vehicle {
    private int doors;
}

@Entity
public class Motorcycle extends Vehicle {
    private boolean hasSidecar;
}

Why use it?

  • Share common fields (no copy-paste!)
  • Query all vehicles at once
  • Keep your code clean and organized

2. Single Table Inheritance 📋

One Big Family Table

Imagine ONE giant notebook where you write about ALL your pets—dogs, cats, birds. You add a label column saying “type: dog” or “type: cat”.

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

@Entity
@DiscriminatorValue("DOG")
public class Dog extends Pet {
    private String breed;
}

@Entity
@DiscriminatorValue("CAT")
public class Cat extends Pet {
    private boolean indoor;
}

The Database View

id pet_type name breed indoor
1 DOG Buddy Labrador null
2 CAT Whiskers null true

Pros: ⚡ Super fast queries! Cons: Many null columns


3. Joined Table Inheritance 🔗

Separate Rooms, Connected Doors

Now imagine each pet type has its OWN notebook, but they all link back to a master pet list.

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

@Entity
public class Manager extends Employee {
    private String department;
}

@Entity
public class Developer extends Employee {
    private String language;
}

The Database View

Employee Table:

id name
1 Alice
2 Bob

Manager Table:

id department
1 Sales

Developer Table:

id language
2 Java

Pros: ✅ No null columns, clean design Cons: 🐌 Slower (needs JOINs)


4. Mapped Superclass 📦

The Invisible Helper

Think of a recipe template. It’s not a dish itself, but every dish you make uses its structure!

A @MappedSuperclass gives fields to children but never becomes its own table.

@MappedSuperclass
public abstract class Auditable {
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    private String createdBy;
}

@Entity
public class Product extends Auditable {
    @Id
    private Long id;
    private String name;
    private double price;
}

@Entity
public class Order extends Auditable {
    @Id
    private Long id;
    private String orderNumber;
}

Result: Both Product and Order tables have createdAt, updatedAt, createdBy columns!

Key Difference from Inheritance:

  • ❌ Cannot query Auditable directly
  • ❌ No Auditable table exists
  • ✅ Just shares fields with children

5. Embeddable Classes 🎁

The Nested Gift Box

Imagine a gift box (your entity) containing a smaller box (embeddable) with jewelry inside. The small box isn’t separate—it’s PART of the gift!

@Embeddable
public class Address {
    private String street;
    private String city;
    private String zipCode;
    private String country;
}

@Entity
public class Customer {
    @Id
    private Long id;
    private String name;

    @Embedded
    private Address homeAddress;

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(
            name = "street",
            column = @Column(
                name = "work_street")),
        @AttributeOverride(
            name = "city",
            column = @Column(
                name = "work_city"))
    })
    private Address workAddress;
}

The Database View

id name street city work_street work_city
1 John Oak St NYC Main Ave Boston

Why use it?

  • 🎯 Group related fields together
  • 🔄 Reuse the same structure
  • 📦 Keep entities clean

6. JPA Attribute Converters 🔮

The Magic Translator

Imagine you speak English, but your database speaks Spanish. A Converter is your translator!

It transforms Java types ↔ Database types automatically.

@Converter(autoApply = true)
public class BooleanToYesNoConverter
    implements AttributeConverter
    <Boolean, String> {

    @Override
    public String convertToDatabaseColumn(
            Boolean value) {
        return value ? "Y" : "N";
    }

    @Override
    public Boolean convertToEntityAttribute(
            String dbValue) {
        return "Y".equals(dbValue);
    }
}

@Entity
public class Settings {
    @Id
    private Long id;

    // Stored as "Y" or "N" in database!
    private Boolean darkMode;

    @Convert(converter =
        JsonToMapConverter.class)
    private Map<String, Object> config;
}

Common Use Cases

Java Type DB Type Why?
Boolean “Y”/“N” Legacy databases
Enum String Readable values
List JSON Flexible storage
LocalDate VARCHAR Custom format

7. JPA Collection Mapping 📚

The Bookshelf Organizer

You have a bookshelf (entity) with many books (collection). JPA helps you organize them in different ways!

ElementCollection - Simple Items

@Entity
public class User {
    @Id
    private Long id;
    private String username;

    @ElementCollection
    @CollectionTable(
        name = "user_phones",
        joinColumns = @JoinColumn(
            name = "user_id"))
    @Column(name = "phone_number")
    private Set<String> phoneNumbers;

    @ElementCollection
    @CollectionTable(name = "user_tags")
    private List<String> tags;
}

Map Collections

@Entity
public class Student {
    @Id
    private Long id;

    // Course name -> Grade
    @ElementCollection
    @MapKeyColumn(name = "course")
    @Column(name = "grade")
    private Map<String, String> grades;
}

Database Result

user_phones table:

user_id phone_number
1 555-1234
1 555-5678

student_grades table:

student_id course grade
1 Math A
1 Science B+

The Complete Picture 🎨

graph LR A["Entity Mapping"] --> B["Inheritance"] A --> C["Embeddables"] A --> D["Converters"] A --> E["Collections"] B --> B1["Single Table"] B --> B2["Joined Table"] B --> B3["Mapped Superclass"] C --> C1["Reusable Components"] D --> D1["Type Translation"] E --> E1["Lists &amp; Maps"]

Quick Reference Card 🃏

Feature Use When…
Single Table Few subclasses, need speed
Joined Table Many fields, need normalization
Mapped Superclass Share fields, no parent queries
Embeddable Group fields, reuse structure
Converter Transform types automatically
Collection Store lists/sets/maps

You Did It! 🎉

You just learned how to:

✅ Create entity hierarchies with inheritance ✅ Choose between Single Table and Joined strategies ✅ Share fields using Mapped Superclass ✅ Embed reusable components ✅ Convert types magically ✅ Map collections to database tables

These are the advanced building blocks that make JPA so powerful. Now go build something amazing!

💡 Pro Tip: Start simple with @MappedSuperclass for sharing audit fields, then explore inheritance when you truly need polymorphic queries!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.