How do I scan packages for components automatically in Spring?

In Spring, component scanning is a feature that allows the framework to detect and register Beans (annotated with @Component, @Service, @Repository, @Controller, or any custom stereotype annotations) automatically during application startup.

Here’s how you can enable and use this feature effectively:

1. Enable Component Scanning in a Java Configuration Class

To enable automatic scanning, use the @ComponentScan annotation in your configuration class. This is commonly used to define the base packages to scan for Spring-managed components.

Example:

package org.kodejava.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "org.kodejava.spring") // Specify base package to scan
public class AppConfig {
}

Here, Spring will scan the org.kodejava.spring package and its sub-packages for any classes annotated with @Component, @Service, @Repository, or @Controller.

2. Use Stereotype Annotations

Add one of the following annotations to your classes to mark them as Spring-managed components:

  • @Component: Generic for any Spring-managed component.
  • @Service: Specifically for service layer components.
  • @Repository: For DAO components (adds exception translation).
  • @Controller/@RestController: For web controllers in a Spring MVC application.

Example:

package org.kodejava.spring.service;

import org.springframework.stereotype.Service;

@Service
public class MyService {
    public String getMessage() {
        return "Hello, Spring Component Scanning!";
    }
}

3. Shortcut with @SpringBootApplication

If you’re using Spring Boot, the @SpringBootApplication annotation already includes component scanning. It automatically scans the package where the main application class resides and its sub-packages.

Example:

package org.kodejava.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // Includes @ComponentScan by default
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

In this case, Spring Boot will scan all components in com.example and its sub-packages automatically.

4. Advanced Configuration (Optional)

a. Scanning Multiple or Specific Packages

You can specify multiple packages to scan:

@ComponentScan(basePackages = {"org.kodejava.spring.service", "org.kodejava.spring.repository"})

b. Filter Components

You can filter which types of components to include or exclude using the includeFilters or excludeFilters attributes of @ComponentScan.

Example:
@ComponentScan(
    basePackages = "org.kodejava.spring",
    includeFilters = @ComponentScan.Filter(MyCustomAnnotation.class),
    excludeFilters = @ComponentScan.Filter(RestController.class)
)

This will scan the org.kodejava.spring package but include only components annotated with @MyCustomAnnotation and exclude all @RestController components.

c. Scan by Custom Annotation

You can create your custom annotation and use it as a filter:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component // Marks it as a Spring component
public @interface MyCustomAnnotation {
}

Then annotate classes using @MyCustomAnnotation and configure the scanner accordingly.

5. XML-based Configuration (Legacy Approach)

If you’re using XML-based configuration (rare in modern Spring apps), you can configure component scanning like this:

<context:component-scan base-package="org.kodejava.spring"/>

6. Tips

  • Place your configuration class or main application class at a high-level base package to ensure all sub-packages are scanned automatically.
  • Avoid scanning unnecessary packages outside your application (e.g., third-party libraries or system packages) to improve performance.
  • Use @Lazy with components for lazy initialization if needed.

By using these approaches, you can enable automatic detection and registration of Spring beans with ease!


Maven Dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.2.6</version>
</dependency>

Maven Central

How do I use @Component, @Autowired, and @Qualifier in Spring?

Spring provides annotations like @Component, @Autowired, and @Qualifier to simplify dependency injection and make applications loosely coupled and modular. Below, we’ll explore these annotations in detail, focusing on their usage and a complete example.

1. @Component Annotation

The @Component annotation marks a class as a Spring-managed bean. It is auto-detected during component scanning, and Spring adds it to the application context.

Usage:

import org.springframework.stereotype.Component;

@Component
public class ExampleComponent {
    public void execute() {
        System.out.println("Component is working!");
    }
}

When the Spring application starts, it automatically scans the classpath for classes annotated with @Component (and its specializations like @Service, @Repository, and @Controller) and registers them as beans in the application context.

2. @Autowired Annotation

The @Autowired annotation is used for automatic dependency injection. It instructs Spring to inject a matching bean from the application context where the annotation is applied.

Types of Injection:

  1. Field Injection:
    @Component
    public class ClientWithFieldInjection {
       @Autowired
       private ExampleComponent exampleComponent;
    
       public void perform() {
           exampleComponent.execute();
       }
    }
    
  2. Setter Injection:
    @Component
    public class ClientWithSetterInjection {
       private ExampleComponent exampleComponent;
    
       @Autowired
       public void setExampleComponent(ExampleComponent exampleComponent) {
           this.exampleComponent = exampleComponent;
       }
    
       public void perform() {
           exampleComponent.execute();
       }
    }
    
  3. Constructor Injection (Preferred):
    @Component
    public class ClientWithConstructorInjection {
       private final ExampleComponent exampleComponent;
    
       @Autowired
       public ClientWithConstructorInjection(ExampleComponent exampleComponent) {
           this.exampleComponent = exampleComponent;
       }
    
       public void perform() {
           exampleComponent.execute();
       }
    }
    
  • Preferred: Constructor injection is considered a best practice because:
    • Dependencies are initialized during object creation, ensuring immutability.
    • It’s easier to write unit tests, as all dependencies can be provided explicitly.

3. @Qualifier Annotation

When multiple beans of the same type exist in the application context, Spring must decide which one to inject. By default, it uses the bean name, but you can explicitly specify which bean to use with the @Qualifier annotation.

Complete Example with Interface, Implementations, and Dependency Injection

Step 1: Define an Interface

Create an abstraction to represent a service contract.

public interface ServiceA {
    void serve();
}

Step 2: Provide Implementations

Implement the ServiceA interface with two different classes.

import org.springframework.stereotype.Component;

@Component("serviceAImpl1")
public class ServiceAImpl1 implements ServiceA {
    @Override
    public void serve() {
        System.out.println("ServiceAImpl1 is serving...");
    }
}

@Component("serviceAImpl2")
public class ServiceAImpl2 implements ServiceA {
    @Override
    public void serve() {
        System.out.println("ServiceAImpl2 is serving...");
    }
}
  • The @Component("serviceAImpl1") and @Component("serviceAImpl2") annotations allow Spring to identify and differentiate the two beans. The specified names (serviceAImpl1 and serviceAImpl2) can be used with the @Qualifier annotation.

Step 3: Inject the Dependency in the Client Class

Create a client class that depends on ServiceA.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class Client {
    private final ServiceA serviceA;

    @Autowired
    public Client(@Qualifier("serviceAImpl1") ServiceA serviceA) { // Use serviceAImpl1
        this.serviceA = serviceA;
    }

    public void run() {
        serviceA.serve();
    }
}
  • @Qualifier("serviceAImpl1"): Ensures that the specific implementation ServiceAImpl1 is injected into the Client class. Without the qualifier, Spring would throw an error due to ambiguity, as multiple beans (serviceAImpl1 and serviceAImpl2) implement the same interface.

Step 4: Application Entry Point

Run the application with @SpringBootApplication to trigger Spring’s component scanning and dependency injection.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        var context = SpringApplication.run(Application.class, args);

        // Get the client bean from the Spring application context
        Client client = context.getBean(Client.class);
        client.run(); // This will call ServiceAImpl1's serve() method.
    }
}

How It Works

  1. Component Scanning:
    • Spring automatically scans for all classes annotated with @Component and registers them as beans in the application context.
  2. Dependency Injection:
    • Spring injects ServiceAImpl1 into Client using the @Autowired and @Qualifier annotations.
  3. Output: Upon running the application, the following message is printed:

ServiceAImpl1 is serving...

Key Advantages of Using Interfaces and Dependency Injection

  • Loose Coupling: The client depends on an abstraction (ServiceA) rather than concrete classes, making the application flexible and easier to maintain.
  • Testability: By using interfaces, you can easily mock or stub dependencies for testing purposes.
  • Flexibility: New implementations can be added and swapped out without changing the client code.

Additional Notes on @Qualifier

  • If only one implementation exists, you don’t need @Qualifier; Spring can find the appropriate bean automatically.
  • If you don’t use @Qualifier, and there are multiple matching beans, Spring throws a NoUniqueBeanDefinitionException.

Final Thoughts

Using @Component, @Autowired, and @Qualifier together allows you to create a clean and modular structure in Spring applications. By programming to an interface, following the best practice of constructor injection, and leveraging qualifiers for resolving ambiguities, you can develop highly extensible and maintainable applications.


Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.2.6</version>
    </dependency>
</dependencies>

Maven Central

How do I define and inject dependencies using annotations in Spring?

In Spring, you can define and inject dependencies using annotations, which simplifies the process of configuring beans and their relationships. Here’s how you can do it step by step:


1. Define a Dependency with @Component

To define a class as a Spring-managed component (or bean), you annotate it with @Component, which makes the class eligible for dependency injection.

package org.kodejava.spring;

import org.springframework.stereotype.Component;

@Component
public class MyDependency {
    public void doSomething() {
        System.out.println("Dependency logic executed.");
    }
}

Here, @Component tells Spring to manage the lifecycle of this class as a bean.


2. Inject the Dependency with @Autowired

You can inject dependencies into another class by using the @Autowired annotation. It can be applied to:

  • Field injection
  • Constructor injection (recommended)
  • Setter injection

A. Field Injection

package org.kodejava.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    @Autowired // Spring automatically injects the MyDependency bean here
    private MyDependency myDependency;

    public void performTask() {
        myDependency.doSomething();
    }
}

B. Constructor Injection (Recommended)

Constructor injection is preferred as it makes the dependencies immutable and facilitates better testing.

package org.kodejava.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private final MyDependency myDependency;

    @Autowired
    public MyService(MyDependency myDependency) {
        this.myDependency = myDependency;
    }

    public void performTask() {
        myDependency.doSomething();
    }
}

Note: From Spring 4.3 onward, if a class has only one constructor, the @Autowired annotation is optional since Spring will automatically use that constructor to inject dependencies.


C. Setter Injection

package org.kodejava.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private MyDependency myDependency;

    @Autowired
    public void setMyDependency(MyDependency myDependency) {
        this.myDependency = myDependency;
    }

    public void performTask() {
        myDependency.doSomething();
    }
}

3. Marking Other Components

Instead of using @Component, Spring provides additional stereotype annotations for specific roles, although they work similarly. These are:

  • @Service: Used for service classes.
  • @Repository: Used for data access/DAO components.
  • @Controller: Used for Spring MVC controllers.

Example:

import org.springframework.stereotype.Service;

@Service
public class MyService {
    public void executeService() {
        System.out.println("Executing service logic...");
    }
}

4. Enable Component Scanning

To ensure Spring automatically discovers and registers your components, you need to enable component scanning using the @ComponentScan annotation in your configuration class.

Example configuration class:

package org.kodejava.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "org.kodejava")
public class AppConfig {
}

Alternatively, if you are using Spring Boot, component scanning is enabled automatically for classes within the same package or sub-packages of the main application class annotated with @SpringBootApplication.


5. Example of Application Setup

Here’s a complete example:

Dependency

package org.kodejava.spring;

import org.springframework.stereotype.Component;

@Component
public class HelloWorldService {
    public String sayHello() {
        return "Hello, World!";
    }
}

Service

package org.kodejava.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class GreetingService {
    private final HelloWorldService helloWorldService;

    @Autowired
    public GreetingService(HelloWorldService helloWorldService) {
        this.helloWorldService = helloWorldService;
    }

    public void printGreeting() {
        System.out.println(helloWorldService.sayHello());
    }
}

Main Application

package org.kodejava.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        GreetingService greetingService = context.getBean(GreetingService.class);
        greetingService.printGreeting();
    }
}

Configuration

package org.kodejava.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "org.kodejava")
public class AppConfig {
}

Summary of Annotations:

  • @Component: Marks a class as a Spring bean.
  • @Service: A specialization of @Component, typically used for service-layer classes.
  • @Repository: A specialization of @Component, used for DAO/repository classes.
  • @Controller: A specialization of @Component, used for Spring MVC controllers.
  • @Autowired: Marks a dependency to be automatically injected by Spring.
  • @ComponentScan: Specifies the base package(s) for scanning components.

This approach makes dependency management clean and reduces boilerplate code compared to XML-based configurations.


Maven Dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.2.6</version>
</dependency>

Maven Central

How do I create my first Spring bean using XML configuration?

Creating your first Spring bean using XML configuration is a straightforward process. Here’s a step-by-step guide:


1. Add Spring Framework to Your Project

Make sure you have Spring dependencies added to your project. If you’re using Maven, include the following dependencies in your pom.xml:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.2.6</version> <!-- Update to a stable version -->
</dependency>

2. Create the Bean Class

Create a simple Java class that will serve as your Spring bean. For example:

HelloWorld.java

package com.example;

public class HelloWorld {
    private String message;

    public void setMessage(String message) { // Setter method for dependency injection
        this.message = message;
    }

    public void getMessage() {
        System.out.println("Your Message: " + message);
    }
}

3. Create the Spring XML Configuration File

Define the bean in an XML configuration file. Commonly, the file is named applicationContext.xml.

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Definition of the HelloWorld bean -->
    <bean id="helloWorld" class="org.kodejava.spring.HelloWorld">
        <property name="message" value="Hello, Spring!"/>
    </bean>

</beans>

Here’s what’s happening:

  • id="helloWorld" specifies the name of the bean.
  • class="org.kodejava.spring.HelloWorld" points to the bean’s class.
  • The <property> tag is used to inject the value for the message property of the HelloWorld class.

4. Create the Main Class to Load the Bean

Write a Main class to load the Spring context and retrieve the bean:

MainApp.java

package org.kodejava.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        // Load the Spring configuration file
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");

        // Retrieve the bean from the Spring container
        HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");

        // Call bean method
        helloWorld.getMessage();
    }
}

5. Run the Application

When you run the MainApp class, you should see the output:

Your Message: Hello, Spring!

Key Points to Remember:

  • XML-based configuration is one of the older ways to configure Spring beans and is still supported, but newer versions prefer Java-based or annotation-based configuration.
  • Ensure the applicationContext.xml file is in the classpath (e.g., under src/main/resources).

That’s it! You’ve successfully created your first Spring bean using XML configuration.

How do I understand IoC and DI in the Spring Framework?

Understanding Inversion of Control (IoC) and Dependency Injection (DI) in the Spring Framework can seem tricky at first, but it becomes intuitive when approached step by step. Here is a simplified explanation:


1. Inversion of Control (IoC)

IoC is a principle in software design where the control of creating and managing objects is transferred (inverted) from the programmer to a framework or container – in this case, Spring.

Traditional Approach vs. IoC

  • Without IoC: Developers create objects and manage dependencies manually.
public class Car {
    private Engine engine;

    public Car() {
        this.engine = new Engine(); // You create the dependency.
    }
}
  • With IoC: Spring container creates and wires the dependencies for you. As a developer, you define what relationships (dependencies) exist, but Spring takes care of initializing and injecting them.
public class Car {
    private Engine engine;

    // Dependency injected via constructor/setter by Spring
    public Car(Engine engine) {
        this.engine = engine;
    }
}

Key Idea: The control of how objects are created is no longer in the class (e.g., Car), but in the IoC container.


2. Dependency Injection (DI)

DI is a specific technique of achieving IoC. It is the process of automatically providing (injecting) dependencies to an object rather than the object creating those dependencies itself.

Spring supports 3 types of DI:

  1. Constructor-based DI
  2. Setter-based DI
  3. Field-based DI (via annotation)

a) Constructor-based DI

Here, dependencies are passed as constructor parameters, ensuring required dependencies are provided during object creation.

@Component
public class Car {
    private final Engine engine;

    @Autowired
    public Car(Engine engine) { // Dependency injected through constructor
        this.engine = engine;
    }
}

b) Setter-based DI

Dependencies are set using setter methods. This gives you flexibility as the object can be initialized without all dependencies being set upfront.

@Component
public class Car {
    private Engine engine;

    @Autowired
    public void setEngine(Engine engine) { // Dependency injected via setter
        this.engine = engine;
    }
}

c) Field-based DI

Dependencies are injected directly into fields using annotations. This simplifies code but reduces testability and violates some design principles since it makes dependencies less explicit.

@Component
public class Car {
    @Autowired
    private Engine engine; // Dependency injected directly
}

3. How IoC and DI Work Together

  • IoC Container: The Spring IoC container is the mechanism responsible for managing the life cycle of objects, resolving dependencies, and injecting them where needed.
  • Bean Configuration: You define dependencies either in XML configuration, Java-based configuration (@Configuration), or annotations like @Component, @Autowired, @Bean, etc.
  • Wiring: Spring resolves dependencies and injects them at runtime using DI.

Example:

package org.kodejava.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class AppConfig {
    @Bean
    public Engine engine() {
        return new Engine();
    }

    @Bean
    public Car car(Engine engine) { // IoC container wires Engine to Car
        return new Car(engine);
    }
}

The IoC container handles:

  1. Creating the Engine object.
  2. Creating the Car object and injecting the Engine into it.

4. Benefits of IoC and DI in Spring

  • Loose Coupling: Classes are less dependent on concrete implementations of their dependencies.
  • Testability: Dependencies can easily be mocked for testing purposes.
  • Flexibility: Swapping dependencies becomes easier without changing much code.
  • Better Code Organization: Centralized dependency configuration improves clarity.
  • Reusability: Services and objects can be reused across the application.

5. Analogies for Easy Understanding

Think of Spring as a restaurant:

  • Menu (Configuration): You tell the restaurant what you need (dependencies) but don’t handle the cooking (creation process).
  • Kitchen (IoC Container): The restaurant’s kitchen decides how meals (objects) are prepared and served to you.
  • Waiter (Dependency Injection): The waiter serves (injects) the prepared meal to you.

In this analogy:

  • You define what you want (configuration).
  • The kitchen (container) takes control.
  • The waiter (DI mechanism) ensures you get everything you need.

6. Practical Example

Using annotations, you can define how IoC and DI work in a Spring application:

Car.java

package org.kodejava.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Car {
    private final Engine engine;

    @Autowired // DI happens here
    public Car(Engine engine) {
        this.engine = engine;
    }

    public void start() {
        System.out.println("Car started with engine: " + engine.getType());
    }
}

Engine.java

package org.kodejava.spring;

import org.springframework.stereotype.Component;

@Component
public class Engine {
    public String getType() {
        return "V8 Engine";
    }
}

Main Application

package org.kodejava.spring;

import org.springframework.context.annotation.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringIoCExample {
    public static void main(String[] args) {
        ApplicationContext context =
                new AnnotationConfigApplicationContext(AppConfig.class);

        Car car = context.getBean(Car.class); // IoC-managed Car instance
        car.start(); // Dependency Engine is automatically injected
    }
}

Output:

Car started with engine: V8 Engine

Recap

  • IoC hands over object creation and injection to the Spring container.
  • DI is the mechanism by which dependencies are injected into a class.

By following the principles of IoC and DI, you achieve more maintainable, testable, and loosely coupled code in your Spring applications!


Maven Dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.2.6</version>
</dependency>

Maven Central

How do I get the auto-generated key in JdbcTemplate?

Spring JDBC simplifies database operations by providing an abstraction layer over traditional JDBC. In this blog post, we’ll walk through a practical example of using Spring JDBC to insert a record into a database and obtain the generated key for the newly inserted record.

First, let’s look at the complete code snippet:

package org.kodejava.spring.jdbc;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import java.math.BigInteger;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;

public class InsertDemoObtainsKey {
    public static void main(String[] args) {
        String insert = "INSERT INTO record (title, release_date, artist_id, label_id, created) VALUES (?, ?, ?, ?, ?)";

        JdbcTemplate template = new JdbcTemplate(new DriverManagerDataSource("jdbc:mysql://localhost/musicdb", "root", ""));
        KeyHolder keyHolder = new GeneratedKeyHolder();

        template.update(con -> {
            PreparedStatement ps = con.prepareStatement(insert, PreparedStatement.RETURN_GENERATED_KEYS);
            ps.setString(1, "Let It Be");
            ps.setDate(2, Date.valueOf(LocalDate.of(1970, Month.MAY, 8)));
            ps.setLong(3, 1L);
            ps.setLong(4, 1L);
            ps.setTimestamp(5, Timestamp.valueOf(LocalDateTime.now()));
            return ps;
        }, keyHolder);

        BigInteger key = (BigInteger) keyHolder.getKeys();
        System.out.println("key = " + key);
    }
}

This code demonstrates how to insert a record into a database table and retrieve the generated key using Spring’s JdbcTemplate.

DataSource Configuration

JdbcTemplate template = new JdbcTemplate(new DriverManagerDataSource("jdbc:mysql://localhost/musicdb", "root", ""));

Here, we create a JdbcTemplate instance, providing it with a DriverManagerDataSource. This data source points to our MySQL database named musicdb, with the username root and an empty password.

SQL Insert Statement

String insert = "INSERT INTO record (title, release_date, artist_id, label_id, created) VALUES (?, ?, ?, ?, ?)";

We define our SQL insert statement with placeholders for the values to be inserted. The table record is assumed to have columns title, release_date, artist_id, label_id, and created.

KeyHolder Initialization

KeyHolder keyHolder = new GeneratedKeyHolder();

A KeyHolder is used to hold the generated keys. In this case, we’re using a GeneratedKeyHolder.

Executing the Update

template.update(con -> {
PreparedStatement ps = con.prepareStatement(insert, PreparedStatement.RETURN_GENERATED_KEYS);
    ps.setString(1, "Let It Be");
    ps.setDate(2, Date.valueOf(LocalDate.of(1970, Month.MAY, 8)));
    ps.setLong(3, 1L);
    ps.setLong(4, 1L);
    ps.setTimestamp(5, Timestamp.valueOf(LocalDateTime.now()));
    return ps;
}, keyHolder);

We use the JdbcTemplate‘s update method, which takes two parameters: a PreparedStatementCreator and a KeyHolder. The PreparedStatementCreator is implemented using a lambda expression that sets the values for the placeholders in our SQL insert statement.

Retrieving the Generated Key

BigInteger key = (BigInteger) keyHolder.getKeys();
System.out.println("key = " + key);

After the update operation, we retrieve the generated key from the KeyHolder. The key is then printed to the console.

Summary

Using Spring JDBC simplifies the process of interacting with the database. In this example, we demonstrated how to insert a record into a MySQL database and retrieve the generated key using JdbcTemplate. This approach ensures clean and manageable code while leveraging the power of Spring’s abstraction over traditional JDBC.

Feel free to experiment with this code, adjusting the database connection details and SQL statements to fit your requirements. Happy coding!

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>6.1.10</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.4.0</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I show Spring transaction in log / console?

When you use the Spring framework @Transactional annotation in your service layer you might want to see what is happening in your code related to database transaction. You want to see when a transaction is started, when it is committed or rollbacked.

To activate the log for transactional message you can add the following configurations in your application properties file. For example when using the JpaTransactionManager you can set the log level to DEBUG.

logging.level.root=INFO

logging.level.org.springframework.orm.jpa=DEBUG
logging.level.org.springframework.transaction=DEBUG

Running the spring boot application with these configuration, the JpaTransactionManager will write something line these on your log file or console:

2023-03-29T23:06:52.194+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [org.kodejava.webapp.accounting.service.impl.CalculationServiceImpl.recalculate]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2023-03-29T23:06:52.194+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(974784570<open>)] for JPA transaction
2023-03-29T23:06:52.195+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@4150907e]
...
...
2023-03-29T23:06:52.195+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(974784570<open>)] for JPA transaction
2023-03-29T23:06:52.195+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
...
...
2023-03-29T23:06:52.237+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2023-03-29T23:06:52.237+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(974784570<open>)]
2023-03-29T23:06:52.237+08:00 DEBUG 54056 --- [nio-9090-exec-3] o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(974784570<open>)] after transaction

How do I combine filter and projection operation in Spring EL?

Using Spring Expression Language (SpEL) we can filter a collection based on some criteria. We can also create a projection of a collection by collecting only a particular property from the collection objects.

Now you know that you have two good features of SpEL that are really powerful to use when working with collection objects manipulation. But you are wondering how to combine both of these filters and projections in one expression. Can you do this in Spring EL? The answer is yes! You can combine them both in one expression. Let’s see an example below.

We are going to use the same configuration used in the previous example:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <util:list id="books">
        <bean class="org.kodejava.spring.core.el.Book" p:title="Essential C# 4.0" p:author="Michaelis" p:pages="450" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="User Stories Applied" p:author="Mike Cohen"
              p:pages="268" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="Learning Android" p:author="Marco Gargenta"
              p:pages="245" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="The Ruby Programming Language"
              p:author="David Flanagan & Yukihiro Matsumoto" p:pages="250" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="Einstein" p:author="Walter Isaacson" p:pages="1000" />
    </util:list>

    <bean id="library" class="org.kodejava.spring.core.el.Library">
        <property name="bookTitles" value="#{books.?[pages gt 250].![title]}" />
    </bean>

</beans>

In the configuration above, when we define the library bean we set its bookTitles property using the filtering and projection operator. First we take only books that have more than 250 pages, and then we create the projection that contains only the book title. So this expression give us all the book’s title of a book that has more than 250 pages.

To make the example complete here again the definition of the Book and the Library class.

package org.kodejava.spring.core.el;

public class Book {
    private Long id;
    private String title;
    private String author;
    private String type;
    private int pages;

    // Getters & Setters
}
package org.kodejava.spring.core.el;

import java.util.List;

public class Library {
    private List<Book> books;
    private List<String> bookTitles;

    // Getters & Setters
}

The main class the run the configuration file:

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELFilterProjectionExample {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-filter-projection.xml")) {

            Library library = context.getBean("library", Library.class);

            for (String title : library.getBookTitles()) {
                System.out.println("title = " + title);
            }
        }
    }
}

The result of the code snippet:

title = Essential C# 4.0
title = User Stories Applied
title = Einstein

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I create a projection of a collection using Spring EL?

In this example you will learn how to create a projection of a collection object. Using projection we can create a new collection with only a specific property from the original collection.

As an example, instead of returning a collection of Book objects we would like only to have the titles of the books. To do this we can use the Spring EL projection operator. The symbol use for this operator is ![].

Let’s begin by creating the Spring configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <util:list id="books">
        <bean class="org.kodejava.spring.core.el.Book" p:title="Essential C# 4.0" p:author="Michaelis" p:pages="450" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="User Stories Applied" p:author="Mike Cohen"
              p:pages="268" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="Learning Android" p:author="Marco Gargenta"
              p:pages="245" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="The Ruby Programming Language"
              p:author="David Flanagan & Yukihiro Matsumoto" p:pages="250" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="Einstein" p:author="Walter Isaacson" p:pages="1000" />
    </util:list>

    <bean id="library" class="org.kodejava.spring.core.el.Library">
        <property name="bookTitles" value="#{books.![title]}" />
    </bean>

</beans>

Here are the definition of the Book and Library class. The getters and setters methods were removed for simplicity of the snippet.

package org.kodejava.spring.core.el;

public class Book {
    private Long id;
    private String title;
    private String author;
    private String type;
    private int pages;

    // Getters & Setters
}
package org.kodejava.spring.core.el;

import java.util.List;

public class Library {
    private List<Book> books;
    private List<String> bookTitles;

    // Getters & Setters
}

Now, let’s talk about the Spring configuration above. The configuration was start by creating a collection of Books using the <util:elements>. The part that use the projection operator is this part of the configuration:

<bean id="library" class="org.kodejava.spring.core.el.Library">
    <property name="bookTitles" value="#{books.![title]}"/>
</bean>

The bean element above create a library bean of type org.kodejava.spring.core.el.Library. We assign the bean’s bookTitles property with values that are a projection of the books collection where we take only the title of the books. ![projectionExpression] is the syntax of the projection operator.

The code snippet below will demonstrate and run our configuration file and print out the result:

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELProjectionExample {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-projection.xml")) {

            Library library = context.getBean("library", Library.class);

            for (String title : library.getBookTitles()) {
                System.out.println("title = " + title);
            }
        }
    }
}

And here are the result:

title = Essential C# 4.0
title = User Stories Applied
title = Learning Android
title = The Ruby Programming Language
title = Einstein

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I filter collection members based on some criteria using Spring EL?

In previous examples you have seen that we use the square-braces [] operator to select items from collection. In this post you will learn how to filter members of a collection with a certain criteria using the Spring EL. To do this Spring EL give you another special operator, the filter operator which can be typed like .?[], you can define the filter criteria inside the braces.

Beside the filter operator .?[] there are also operator that can select the first and the last matching items from collection. You can use the .^[] for selecting the first match and the .$[] operator to select the last match items from collection respectively.

As an example we will demonstrate here that we want to find a collection of books that have pages more than 250 and assign it to Library bean’s books properties. So let’s begin by defining a class called Book and Library which will have the following properties:

package org.kodejava.spring.core.el;

public class Book {
    private Long id;
    private String title;
    private String author;
    private String type;
    private int pages;

    // Getters & Setters

    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", pages=" + pages +
                '}';
    }
}
package org.kodejava.spring.core.el;

import java.util.List;

public class Library {
    private List<Book> books;

    public List<Book> getBooks() {
        return books;
    }

    public void setBooks(List<Book> books) {
        this.books = books;
    }
}

After creating the Book and the Library class let’s now create the Spring configuration file for our demo. We will create a file and call it as spel-filter-collection.xml with the following lines of configuration in it.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <util:list id="books">
        <bean class="org.kodejava.spring.core.el.Book" p:title="Essential C# 4.0" p:author="Michaelis" p:pages="450" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="User Stories Applied" p:author="Mike Cohen"
              p:pages="268" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="Learning Android" p:author="Marco Gargenta"
              p:pages="245" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="The Ruby Programming Language"
              p:author="David Flanagan & Yukihiro Matsumoto" p:pages="250" />
        <bean class="org.kodejava.spring.core.el.Book" p:title="Einstein" p:author="Walter Isaacson" p:pages="1000" />
    </util:list>

    <bean id="lib1" class="org.kodejava.spring.core.el.Library">
        <property name="books" value="#{books.?[pages gt 250]}" />
    </bean>

    <bean id="lib2" class="org.kodejava.spring.core.el.Library">
        <property name="books" value="#{books.^[pages gt 250]}" />
    </bean>

    <bean id="lib3" class="org.kodejava.spring.core.el.Library">
        <property name="books" value="#{books.$[pages gt 250]}" />
    </bean>

</beans>

The first thing that you can see in the configuration above is the <util-list> where we create a list of Book beans. Next we have three beans definition of the type Library where the books property was assigned with a collection of beans selected from the books list.

The lib1 will contains books that have pages more than 250. The lib2 will contains the first book found to have more than 250 pages while the lib3 will contains the last book found to have more than 250 pages.

Below is the code that will run our configuration file and the example output it will produce.

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELFilterCollection {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-filter-collection.xml")) {

            System.out.println("Library 1");
            Library lib1 = (Library) context.getBean("lib1");
            for (Book book : lib1.getBooks()) {
                System.out.println("    Book = " + book);
            }

            System.out.println("Library 2");
            Library lib2 = (Library) context.getBean("lib2");
            for (Book book : lib2.getBooks()) {
                System.out.println("    Book = " + book);
            }

            System.out.println("Library 3");
            Library lib3 = (Library) context.getBean("lib3");
            for (Book book : lib3.getBooks()) {
                System.out.println("    Book = " + book);
            }
        }
    }
}
Library 1
    Book = Book{title='Essential C# 4.0', author='Michaelis', pages=450}
    Book = Book{title='User Stories Applied', author='Mike Cohen', pages=268}
    Book = Book{title='Einstein', author='Walter Isaacson', pages=1000}
Library 2
    Book = Book{title='Essential C# 4.0', author='Michaelis', pages=450}
Library 3
    Book = Book{title='Einstein', author='Walter Isaacson', pages=1000}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central