Skip to main content

πŸ’₯ "Wait... Why Is It NULL?!?" — When @Value("${...}") Ignores Your Static Field 😡‍πŸ’«

πŸ”  A surprising Spring Boot moment I didn't expect — and the rabbit hole it took me down...

🎬 It All Started With a Simple Idea...

You know how it goes…

You define a config value like this in application.properties:

payment.currency=INR

And then you boldly write this innocent-looking code:

@Component
public class PaymentUtil {

    @Value("${payment.currency}")
    private static String currency; // ✅ Logical! Right?

    public static void printCurrency() {
        System.out.println("Currency: " + currency);
    }
}

You run the app. And BAM πŸ’₯

Currency: null

😡 "Eh? I clearly defined the property. Is it not reading the file? Do I need a restart? Do I need to yell at my laptop?"

🀯 The Shocking Discovery

Spring doesn’t inject values into static fields.

Yes, my friend. Even if you beg it with @Value.

And trust me — it’s not a bug. It’s a feature. πŸ™ƒ

🧠 What Is This Dependency Injection (DI) Sorcery Anyway?

Let’s take a detour (the good kind — not the Bangalore traffic kind).

Spring uses Dependency Injection (DI) to manage your object graph using:

  • πŸ“Œ @Component / @Service / @Repository
  • πŸ“Œ @Autowired / @Value / Constructor injection
  • πŸ“Œ Reflection magic 🎩✨

🚧 Why Static Fields Break the Magic

Spring manages beans as instances — objects in the ApplicationContext.

But static fields belong to the class itself, not an object.

// Instance-level: Works ✔️
@Component
public class ConfigReader {
    @Value("${app.name}")
    private String name;
}

// Static field: No bean owns it ❌
@Value("${app.name}")
private static String name;

So Spring scans the class and goes:

“Aha, no instance variable to inject into? Cool, I’ll move on.” 😎

That’s why:

  • ❌ You get null
  • ❌ Or default values
  • ❌ Or you stare at the screen questioning your life choices 🫠

πŸ› ️ The Correct Fix That Surprised Me

✅ Option 1: Use @PostConstruct to Bridge Static + Instance

@Component
public class PaymentUtil {

    @Value("${payment.currency}")
    private String currency;

    private static String staticCurrency;

    @PostConstruct
    public void init() {
        staticCurrency = currency;
    }

    public static String getCurrency() {
        return staticCurrency;
    }
}

πŸŽ‰ Now currency is injected properly by Spring.

✅ Option 2: Use @ConfigurationProperties — The Cleaner Way

@Component
@ConfigurationProperties(prefix = "payment")
public class PaymentConfig {
    private String currency;

    public String getCurrency() { return currency; }
    public void setCurrency(String currency) { this.currency = currency; }
}
@Component
public class PaymentUtil {
    private final PaymentConfig config;

    public PaymentUtil(PaymentConfig config) {
        this.config = config;
    }

    public void printCurrency() {
        System.out.println("Currency: " + config.getCurrency());
    }
}

🧼 Much cleaner, and easier to unit test!

🧠 But Wait… Why Can’t Spring Just Inject Into Static?

Let’s dig deeper.

  1. πŸ“¦ Create object of the bean (e.g., PaymentUtil)
  2. πŸ” Reflectively access fields
  3. πŸ’‰ Inject values from application context
  4. πŸš€ Initialize the bean

But static fields don’t belong to any bean instance. So Step 2 breaks:

🧡 “Oops! There’s no object for me to inject into.”

It’s like trying to insert a USB drive into a photo of a laptop. πŸ™ƒ

πŸ˜‚ Dumb Interview Question, Smart Answer

Q: "Can Spring inject values into static fields?"

A: "Only if Spring becomes a Jedi and rewrites the Java language spec."

πŸ§ͺ Curious? Try This Yourself!

# application.properties
payment.currency=USD
@Component
public class TestUtil {
    @Value("${payment.currency}")
    private static String currency;

    public static void main(String[] args) {
        System.out.println("Currency = " + currency);
    }
}
Currency = null  // 😐

🧼 So What Did I Learn?

  • 😲 I Did This: @Value on a static field
  • πŸ€” Expected: "INR"
  • ❌ Got: null
  • ✅ Fixed By: @PostConstruct or @ConfigurationProperties
  • πŸ’‘ Lesson: Spring doesn’t inject into static — by design

🌈 Wrapping Up: From "What The Null?!" to "Aha!"

This was a “Why is it null?” moment that led to one of my best Spring learnings:

Spring is smart, but it only manages beans it creates.

Static fields live in their own world — away from the Spring container.

Always remember: With great power comes great bean lifecycle responsibility. πŸ•Έ️

🎀 Over to You!

Ever had a “Null surprise” like this in your config or bean wiring?

πŸ‘‰ Share your moment in the comments — let’s laugh and learn together! πŸ˜„

Comments

Popular posts from this blog

🐱 Tomcat vs ⚡ Netty – Which One Should You Use?

🐱 Tomcat vs ⚡ Netty – Which One Should You Use? So recently I got curious about this too πŸ€”. Everywhere in Spring Boot tutorials we see Tomcat . Then suddenly while exploring Spring WebFlux , the name Netty pops up. And I was like – “Wait, who’s this Netty guy trying to replace Tomcat?” πŸ˜… Let’s break it down with real-time examples , icons , and fun comparisons . 🐱 Tomcat – The Traditional Web Server Type: Servlet Container (blocking I/O) World: Used with Spring MVC Style: Thread-per-request model πŸ‘©‍πŸ’» Pros: Stable, widely used, battle-tested Cons: Struggles with huge concurrent connections πŸ‘‰ Example in real life: Tomcat is like a restaurant with fixed waiters 🍴. - Each customer = one thread/waiter - If too many customers come in at once → waiters run out → customers wait outside πŸšͺ ⚡ Netty – The Reactive Rockstar Type: Asynchronous Event-Driven Network Framework World: Default for Spring WebFlux Style: Event-lo...

🎭 Spring’s Secret: Why @Transactional & Friends Betray You Silently

πŸ’‘ Lesson Learned — Not a Prod Bug, But a Real Pain No, this wasn’t a production outage. Nobody screamed at me. But I sat for 3 hours wondering: “Why the heck is my @Transactional not rolling back!?” 😡‍πŸ’« “Why is Redis cache not working?” 🀯 Turned out, the issue was one silent villain: 🧱 Self-invocation 🀷 What Is @Transactional ? If you're new: @Transactional = Tells Spring to start a DB transaction when a method is called. It’ll commit if everything’s okay. It’ll rollback if something fails. 🧠 Think of it like wrapping your code in: try { beginTransaction(); // your logic commit(); } catch(Exception e) { rollback(); } πŸ•΅️ Real-Life Analogy — The Gateway Community 🏘️ Let me tell you about my society — it has a strict watchman at the gate. Here’s how it works: πŸ›‚ Watchman = Spring Proxy 🏠 Your apartment = Your service class πŸšͺ Your room = A method inside that class πŸƒ Scenario 1: Outsider Visits Your friend from outside...

🌟 My Journey – From Zero to Senior Java Tech Lead 🌟

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. πŸ’― Sounds crazy? Let me take you back. πŸ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . πŸ§ͺ Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...