eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – Spring Sale 2026 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 30% off until 31st March, 2026

>> EXPLORE ACCESS NOW

Partner – Diagrid – NPI EA (cat= Testing)
announcement - icon

In distributed systems, managing multi-step processes (e.g., validating a driver, calculating fares, notifying users) can be difficult. We need to manage state, scattered retry logic, and maintain context when services fail.

Dapr Workflows solves this via Durable Execution which includes automatic state persistence, replaying workflows after failures and built-in resilience through retries, timeouts and error handling.

In this tutorial, we'll see how to orchestrate a multi-step flow for a ride-hailing application by integrating Dapr Workflows and Spring Boot:

>> Dapr Workflows With PubSub

Course – Spring Sale 2026 – NPI (cat=Baeldung)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 30% off until 31st March, 2026

>> EXPLORE ACCESS NOW

1. Introduction

When working with Java’s native serialization combined with SonarQube’s code evaluation tool, sometimes we encounter “Fields in a ‘Serializable’ class should either be ‘transient’ or ‘Serializable'” (rule key: java:S1948) warning. This rule is an important guardrail and it prevents a common runtime failure: the NotSerializableException.

In this tutorial, we’ll explore why this warning occurs. Also, we’ll talk about the underlying mechanics of Java serialization, and the best strategies to resolve it.

2. Understanding the Serialization Contract

To make a Java object serializable, its class must implement the java.io.Serializable interface. This is a marker interface that tells the JVM the object’s state is converted into a byte stream for storage or network transfer.

As such, the fundamental rule of this contract is recursive: if a class is serializable, all its non-static and non-transient member fields must also be serializable. If the serialization mechanism encounters a field that doesn’t implement Serializable and isn’t marked as transient, the process will fail at runtime. Sonar flags these fields during static analysis and helps us catch this error before the code even runs.

In addition, it’s important to remember that serialization isn’t just about the top-level class; it’s about the entire object graph.

3. Reproducing the Sonar Warning

Let’s look at a typical scenario that triggers the java:s1948 warning. First, let’s add the SLF4J dependency to our pom.xml:

<dependency>
    <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
     <version>2.0.17</version>
</dependency>

Now, let’s create a User class that we want to store in a distributed session or cache. This class also contains a reference to another class, Address, which does not implement the Serializable interface. We’ll start with a simple implementation:

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
         
    private String username;
    private Address address; // Sonar Warning: Make "address" transient or serializable
    private final Logger logger = LoggerFactory.getLogger(User.class); // Sonar Warning
         
     public User(String username, Address address) {
        this.username = username;
        this.address = address;
     }
}

In this example, the User class correctly implements Serializable. However, if the Address class is defined without the interface, Sonar will flag the address field. Similarly, since the SLF4J Logger does not implement Serializable, it will also trigger the warning. Furthermore, if we try to serialize an instance of User, the JVM will throw a NotSerializableException at runtime. This is exactly what Sonar is trying to help us avoid. Now, let’s look at some ways we can tackle this warning.

4. Making the Field Serializable

The most straightforward fix is to ensure that the nested class also implements the Serializable interface. This is the preferred approach when the field represents a core part of the object’s state that must be preserved. As such, if we own the source code of the nested object, we should simply update the class definition:

public class Address implements Serializable {
    private static final long serialVersionUID = 1L;
        
    private String street;
    private String city;
        
    public Address(String street, String city) {
        this.street = street;
        this.city = city;
    }
}

By adding implements Serializable and providing a serialVersionUID, we satisfy the contract requirements. It’s a best practice to always include serialVersionUID to ensure compatibility during the deserialization process. Especially if the class structure evolves over time.

5. Using the static Modifier

Another effective way to resolve the warning for certain fields is to declare them as static. In Java, static fields are not serialized because they belong to the class itself rather than a specific instance. Since they are excluded from the serialization process by the JVM, SonarQube does not flag them.

This is the standard solution for loggers and constants:

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
       
    private static final Logger logger = LoggerFactory.getLogger(User.class); // No Warning
    private String username;
    private Address address;

    // getters, setters ...
 }

By making the logger static, the warning disappears, and we follow the common Java pattern for logger declarations. This approach is ideal for any field that is shared across all instances of the class and does not represent the unique state of an individual object.

6. Leveraging the transient Keyword

If a field is instance-specific but shouldn’t be serialized (like a reference to a temporary cache, or a non-serializable third-party object) we use the transient keyword. This modifier tells the JVM to skip the field during the serialization process:

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
       
    private String username;
    private Address address;
    private transient List<String> temporaryCache; // Warning Resolved

    // getters and setters ...
}

We need to take into consideration that when an object is deserialized, all transient fields are initialized to their default values: null for objects and 0 for primitives. As such, if a transient field is required for the object to function after being restored, we must re-initialize it. A way to achieve this is to use the readObject method:

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    this.temporaryCache = new ArrayList<>();
}

7. Handling Framework Dependencies

In modern Java frameworks like Spring, this warning often appears in @SessionScoped beans when injecting a @Service or @Repository. Since these services are managed by the container and typically aren’t serializable, they should be marked as transient:

@SessionScoped
public class UserPreferences implements Serializable {
    @Autowired
    private transient PreferenceService service; // Fixed by marking it with transient
}

Spring handles the dependency injection, so it will re-inject the service when the bean is restored from the session, provided the framework’s proxy mechanism supports it. This keeps our session-scoped beans serializable while allowing them to interact with stateless services.

Furthermore, we might encounter situations where we use third-party library classes that do not implement Serializable. If we cannot modify their source code, we have two main options:

  • Wrap the object: Create a serializable DTO that holds only the necessary primitive data.\
  • Custom Serialization: Use transient for the third-party object and manually handle its state during serialization using the writeObject and readObject methods.

For example, if we have a non-serializable Metadata object, we can store its state as a serializable Map or and reconstruct it upon deserialization. This keeps our domain models serializable while still utilizing powerful third-party tools.

8. Conclusion

In this tutorial, we’ve covered how to handle the Sonar warning “Make Transient or Serializable”. Although the warning is helpful to ensure runtime stability in Java applications, it can cause confusion. As such, by understanding the recursive nature of Java serialization, we can choose the correct fix based on the field’s role in our application.

Implement Serializable if the field is a core part of the object’s state. Use static for loggers, constants and shared class-level members. Mark as transient if the field is a resource, or temporary data. Refactor the design if we’re trying to serialize stateless services or third-party objects that aren’t meant to be persisted.

As always, the code is available over on GitHub.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – Spring Sale 2026 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 30% off until 31st March, 2026

>> EXPLORE ACCESS NOW

Course – Spring Sale 2026 – NPI (All)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 30% off until 31st March, 2026

>> EXPLORE ACCESS NOW

eBook Jackson – NPI EA – 3 (cat = Jackson)
guest
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments