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

TuanhdotnetTuanhdotnet
5 min read

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
}

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
}

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
}

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
}

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
}

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);
}
}

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
}

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 more at : Using @MappedSuperclass in JPA: Code Examples, Demos, and Results

0
Subscribe to my newsletter

Read articles from Tuanhdotnet directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tuanhdotnet
Tuanhdotnet

I am Tuanh.net. As of 2024, I have accumulated 8 years of experience in backend programming. I am delighted to connect and share my knowledge with everyone.