DEV Community

Anh Trần Tuấn
Anh Trần Tuấn

Posted on • Originally published at tuanh.net on

Using @MappedSuperclass in JPA: Code Examples, Demos, and Results

1. What is @MappedSuperclass in JPA?

@MappedSuperclass is a JPA annotation used to define classes that can pass down their mappings to subclasses. However, unlike @Entity classes, @MappedSuperclass itself is not recognized as an entity and cannot be directly queried by JPA. Instead, it serves as a base class to provide common fields or methods for entity classes.

Image

By marking a class as a @MappedSuperclass , you define a parent class that can house shared attributes such as id, createdAt, or updatedAt. These fields and their mappings will then be inherited by the entities extending the superclass. This helps in reducing duplication and keeping your entity structure DRY (Don’t Repeat Yourself).

1.1 Why use @MappedSuperclass?

One of the main reasons to use @MappedSuperclass is to avoid repetitive code. For example, many entities require fields like createdAt , updatedAt , and createdBy. Instead of adding these fields and their mappings to each entity class, you can define them in a @MappedSuperclass. This centralizes the common logic and helps you maintain a cleaner, more manageable codebase.

Example:

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    // Getters and setters
}
Enter fullscreen mode Exit fullscreen mode

Now, any entity class that extends BaseEntity will automatically inherit these fields.

1.2 How to Implement @MappedSuperclass?

Implementing @MappedSuperclass is relatively straightforward. The following sections will guide you through the steps of creating a mapped superclass and then extending it in your entities.

Creating the Mapped Superclass

First, define the class you want to use as your base class and annotate it with @MappedSuperclass. In this class, you can add fields, mappings, and methods that will be shared across all subclasses.

Example:

@MappedSuperclass
public class Auditable {
    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "modified_by")
    private String modifiedBy;

    // Constructors, getters, and setters
}
Enter fullscreen mode Exit fullscreen mode

Extending the Superclass

Once you’ve created your @MappedSuperclass , the next step is to extend it in your entity classes. These subclasses will inherit the fields and mappings from the superclass but can also define additional attributes.

@Entity
@Table(name = "users")
public class User extends Auditable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username")
    private String username;

    @Column(name = "email")
    private String email;

    // Getters, setters, and additional methods
}
Enter fullscreen mode Exit fullscreen mode

In this example, the User entity inherits the createdBy and modifiedBy fields from the Auditable superclass.

Demo: Creating a User Entity with @MappedSuperclass

Let’s walk through a quick demo of how this works in a Spring Boot JPA project.

Step 1: Define the Base Class

@MappedSuperclass
public abstract class AuditableEntity {
    @Column(name = "created_date")
    private LocalDateTime createdDate;

    @Column(name = "modified_date")
    private LocalDateTime modifiedDate;

    // Getters and Setters
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Extend the Base Class in an Entity

@Entity
@Table(name = "products")
public class Product extends AuditableEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "product_name")
    private String productName;

    @Column(name = "price")
    private Double price;

    // Getters and setters
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Save and Query Data

public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public Product createProduct(Product product) {
        product.setCreatedDate(LocalDateTime.now());
        product.setModifiedDate(LocalDateTime.now());
        return productRepository.save(product);
    }
}
Enter fullscreen mode Exit fullscreen mode

Result:

When a Product entity is saved, the fields from AuditableEntity ( createdDate , modifiedDate ) will also be saved, reducing the need to duplicate these common properties in every entity.

1.4 Advanced Use: Adding Auditing with @MappedSuperclass

A common use case for @MappedSuperclass is to include auditing features in your entities. Let’s enhance our previous example by automatically tracking when an entity is created and last updated.

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity {
    @CreatedDate
    @Column(name = "created_date", updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    @Column(name = "modified_date")
    private LocalDateTime modifiedDate;

    // Getters and Setters
}
Enter fullscreen mode Exit fullscreen mode

In this case, JPA’s auditing feature will automatically populate these fields whenever a new record is created or updated.

2. Best Practices for Using @MappedSuperclass

While @MappedSuperclass is a useful tool, there are several best practices to keep in mind to ensure you are using it effectively and avoid common pitfalls.

2.1 Do Not Use @MappedSuperclass for Querying

Because @MappedSuperclass defines a class that is not a persistent entity, you cannot query it directly. Use it purely as a means of sharing common attributes across your entities.

2.2 Use @MappedSuperclass for Reusable Attributes, Not Behavior

It’s important to use @MappedSuperclass only for sharing attributes, not behavior. If you need to share behavior between entities (e.g., methods), consider using inheritance or interfaces.

2.3 Avoid Overcomplicating with Deep Hierarchies

If you use @MappedSuperclass too frequently or in deeply nested inheritance hierarchies, it can lead to code that is difficult to maintain. Keep your hierarchy shallow and only use @MappedSuperclass when necessary.

3. Conclusion

The @MappedSuperclass annotation provides an efficient way to share common mappings across entities, reducing redundancy in your JPA codebase. Whether you're creating audit trails, centralizing entity attributes, or just keeping your code DRY, this technique can be a vital part of your JPA toolkit.

By understanding how to implement and use @MappedSuperclass in your JPA project, you can streamline your entity management and improve the maintainability of your application.

If you have any questions or need further clarification, feel free to comment below!

Read posts more at : Using @MappedSuperclass in JPA: Code Examples, Demos, and Results

AWS Q Developer image

Your AI Code Assistant

Ask anything about your entire project, code and get answers and even architecture diagrams. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Start free in your IDE

Top comments (0)

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay