Category: Java

Java is a class-based, object-oriented programming language that is designed to have as few implementation dependencies as possible.
Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of the underlying computer architecture.

How to check if a File or Directory exists in Java
03
Mar
2021

How to check if a File or Directory exists in Java

In this quick and short article, you’ll find two examples demonstrating how to check if a File or Directory exists at a given path in Java.
We’re going to get familiar with different ways to check the existence of a file or directory.

Check if a File/Directory exists using Java IO’s File.exists()

import java.io.File;

public class CheckFileExists1 {
    public static void main(String[] args) {

        File file = new File("/Users/callicoder/demo.txt");

        if(file.exists()) {
            System.out.printf("File %s exists%n", file);
        } else {
            System.out.printf("File %s doesn't exist%n", file);
        }

    }
}

Check if a File/Directory exists using Java NIO’s Files.exists() or Files.notExists()

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class CheckFileExists {
    public static void main(String[] args) {

        Path filePath = Paths.get("/Users/callicoder/demo.txt");

        // Checking existence using Files.exists
        if(Files.exists(filePath)) {
            System.out.printf("File %s exists%n", filePath);
        } else {
            System.out.printf("File %s doesn't exist%n", filePath);
        }


        // Checking existence using Files.notExists
        if(Files.notExists(filePath)) {
            System.out.printf("File %s doesn't exist%n", filePath);
        } else {
            System.out.printf("File %s exists%n", filePath);
        }
    }
}
A Guide to JPA with Spring
26
Mar
2021

A Guide to JPA with Spring

This tutorial shows how to set up Spring with JPA, using Hibernate as a persistence provider.

For a step by step introduction about setting up the Spring context using Java-based configuration and the basic Maven pom for the project, see this article.

We’ll start by setting up JPA in a Spring Boot project, then we’ll look into the full configuration we need if we have a standard Spring project.

JPA in Spring Boot

The Spring Boot project is intended to make creating Spring applications much faster and easier. This is done with the use of starters and auto-configuration for various Spring functionalities, JPA among them.

2.1. Maven Dependencies

To enable JPA in a Spring Boot application, we need the spring-boot-starter and spring-boot-starter-data-jpa dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

The spring-boot-starter contains the necessary auto-configuration for Spring JPA. Also, the spring-boot-starter-jpa project references all the necessary dependencies such as hibernate-core.

2.2. Configuration

Spring Boot configures Hibernate as the default JPA provider, so it’s no longer necessary to define the entityManagerFactory bean unless we want to customize it.

Spring Boot can also auto-configure the dataSource bean, depending on the database we’re using. In the case of an in-memory database of type H2HSQLDB, and Apache Derby, Boot automatically configures the DataSource if the corresponding database dependency is present on the classpath.

For example, if we want to use an in-memory H2 database in a Spring Boot JPA application, we only need to add the h2 dependency to the pom.xml file:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.200</version>
</dependency>

This way, we don’t need to define the dataSource bean, but we can do so if we want to customize it.

If we want to use JPA with MySQL database, then we need the mysql-connector-java dependency, as well as to define the DataSource configuration.

We can do this in a @Configuration class, or by using standard Spring Boot properties.

The Java configuration looks the same as it does in a standard Spring project:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUsername("mysqluser");
    dataSource.setPassword("mysqlpass");
    dataSource.setUrl(
      "jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true"); 
    
    return dataSource;
}

To configure the data source using a properties file, we have to set properties prefixed with spring.datasource:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=mysqluser
spring.datasource.password=mysqlpass
spring.datasource.url=
  jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true

Spring Boot will automatically configure a data source based on these properties.

Also in Spring Boot 1, the default connection pool was Tomcat, but with Spring Boot 2 it has been changed to HikariCP.

As we can see, the basic JPA configuration is fairly simple if we’re using Spring Boot.

However, if we have a standard Spring project, then we need more explicit configuration, using either Java or XML. That’s what we’ll focus on in the next sections.

3. The JPA Spring Configuration With Java – in a Non-Boot Project

To use JPA in a Spring project, we need to set up the EntityManager.

This is the main part of the configuration and we can do it via a Spring factory bean. This can be either the simpler LocalEntityManagerFactoryBean or the more flexible LocalContainerEntityManagerFactoryBean.

Let’s see how we can use the latter option:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em 
        = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
      em.setJpaProperties(additionalProperties());

      return em;
   }
   
   // ...

}

We also need to explicitly define the DataSource bean we’ve used above:

@Bean
public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/spring_jpa");
    dataSource.setUsername( "tutorialuser" );
    dataSource.setPassword( "tutorialmy5ql" );
    return dataSource;
}

The final part of the configuration are the additional Hibernate properties and the TransactionManager and exceptionTranslation beans:

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

    return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
    return new PersistenceExceptionTranslationPostProcessor();
}

Properties additionalProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
       
    return properties;
}

4. The JPA Spring Configuration With XML

Next, let’s see the same Spring Configuration with XML:

<bean id="myEmf" 
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.baeldung.persistence.model" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
        </props>
    </property>
</bean>

<bean id="dataSource" 
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/spring_jpa" />
    <property name="username" value="tutorialuser" />
    <property name="password" value="tutorialmy5ql" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven />

<bean id="persistenceExceptionTranslationPostProcessor" class=
  "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

There’s a relatively small difference between the XML and the new Java-based configuration. Namely, in XML, a reference to another bean can point to either the bean or a bean factory for that bean.

In Java, however, since the types are different, the compiler doesn’t allow it, and so the EntityManagerFactory is first retrieved from its bean factory and then passed to the transaction manager:

transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

5. Going Full XML-less

Usually, JPA defines a persistence unit through the META-INF/persistence.xml file. Starting with Spring 3.1, the persistence.xml is no longer necessary. The LocalContainerEntityManagerFactoryBean now supports a packagesToScan property where the packages to scan for @Entity classes can be specified.

This file was the last piece of XML we need to remove. We can now set up JPA fully with no XML.

We would usually specify JPA properties in the persistence.xml file. Alternatively, we can add the properties directly to the entity manager factory bean:

factoryBean.setJpaProperties(this.additionalProperties());

As a side note, if Hibernate would be the persistence provider, then this would be the way to specify Hibernate specific properties as well.

6. The Maven Configuration

In addition to the Spring Core and persistence dependencies – show in detail in the Spring with Maven tutorial – we also need to define JPA and Hibernate in the project, as well as a MySQL connector:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.2.17.Final</version>
   <scope>runtime</scope>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.19</version>
   <scope>runtime</scope>
</dependency>

Note that the MySQL dependency is included here as an example. We need a driver to configure the datasource, but any Hibernate-supported database will do.

7. Conclusion

This tutorial illustrated how to configure JPA with Hibernate in Spring in both a Spring Boot and a standard Spring application.

A Comparison Between Spring and Spring Boot
26
Mar
2021

A Comparison Between Spring and Spring Boot

What Is Spring?

Simply put, the Spring framework provides comprehensive infrastructure support for developing Java applications.

It’s packed with some nice features like Dependency Injection, and out of the box modules like:

  • Spring JDBC
  • Spring MVC
  • Spring Security
  • Spring AOP
  • Spring ORM
  • Spring Test

These modules can drastically reduce the development time of an application.

For example, in the early days of Java web development, we needed to write a lot of boilerplate code to insert a record into a data source. By using the JDBCTemplate of the Spring JDBC module, we can reduce it to a few lines of code with only a few configurations.

3. What Is Spring Boot?

Spring Boot is basically an extension of the Spring framework, which eliminates the boilerplate configurations required for setting up a Spring application.

It takes an opinionated view of the Spring platform, which paves the way for a faster and more efficient development ecosystem.

Here are just a few of the features in Spring Boot:

  • Opinionated ‘starter’ dependencies to simplify the build and application configuration
  • Embedded server to avoid complexity in application deployment
  • Metrics, Health check, and externalized configuration
  • Automatic config for Spring functionality – whenever possible

Let’s get familiar with both of these frameworks step by step.

4. Maven Dependencies

First of all, let’s look at the minimum dependencies required to create a web application using Spring:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.5</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.5</version>
</dependency>

Unlike Spring, Spring Boot requires only one dependency to get a web application up and running:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.4.4</version>
</dependency>

All other dependencies are added automatically to the final archive during build time.

Another good example is testing libraries. We usually use the set of Spring Test, JUnit, Hamcrest, and Mockito libraries. In a Spring project, we should add all of these libraries as dependencies.

Alternatively, in Spring Boot we only need the starter dependency for testing to automatically include these libraries.

Spring Boot provides a number of starter dependencies for different Spring modules. Some of the most commonly used ones are:

  • spring-boot-starter-data-jpa
  • spring-boot-starter-security
  • spring-boot-starter-test
  • spring-boot-starter-web
  • spring-boot-starter-thymeleaf

For the full list of starters, also check out the Spring documentation.

5. MVC Configuration

Let’s explore the configuration required to create a JSP web application using both Spring and Spring Boot.

Spring requires defining the dispatcher servlet, mappings, and other supporting configurations. We can do this using either the web.xml file or an Initializer class:

public class MyWebAppInitializer implements WebApplicationInitializer {
 
    @Override
    public void onStartup(ServletContext container) {
        AnnotationConfigWebApplicationContext context
          = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.baeldung");
 
        container.addListener(new ContextLoaderListener(context));
 
        ServletRegistration.Dynamic dispatcher = container
          .addServlet("dispatcher", new DispatcherServlet(context));
         
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

We also need to add the @EnableWebMvc annotation to a @Configuration class, and define a view-resolver to resolve the views returned from the controllers:

@EnableWebMvc
@Configuration
public class ClientWebConfig implements WebMvcConfigurer { 
   @Bean
   public ViewResolver viewResolver() {
      InternalResourceViewResolver bean
        = new InternalResourceViewResolver();
      bean.setViewClass(JstlView.class);
      bean.setPrefix("/WEB-INF/view/");
      bean.setSuffix(".jsp");
      return bean;
   }
}

By comparison, Spring Boot only needs a couple of properties to make things work once we add the web starter:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

All of the Spring configuration above is automatically included by adding the Boot web starter through a process called auto-configuration.

What this means is that Spring Boot will look at the dependencies, properties, and beans that exist in the application and enable configuration based on these.

Of course, if we want to add our own custom configuration, then the Spring Boot auto-configuration will back away.

5.1. Configuring Template Engine

Now let’s learn how to configure a Thymeleaf template engine in both Spring and Spring Boot.

In Spring, we need to add the thymeleaf-spring5 dependency and some configurations for the view resolver:

@Configuration
@EnableWebMvc
public class MvcWebConfig implements WebMvcConfigurer {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = 
          new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/WEB-INF/views/");
        templateResolver.setSuffix(".html");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        templateEngine.setEnableSpringELCompiler(true);
        return templateEngine;
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        registry.viewResolver(resolver);
    }
}

Spring Boot 1 only requires the dependency of spring-boot-starter-thymeleaf to enable Thymeleaf support in a web application. Due to the new features in Thymeleaf3.0, we also have to add thymeleaf-layout-dialect as a dependency in a Spring Boot 2 web application. Alternatively, we can choose to add a spring-boot-starter-thymeleaf dependency that’ll take care of all of this for us.

Once the dependencies are in place, we can add the templates to the src/main/resources/templates folder and the Spring Boot will display them automatically.

6. Spring Security Configuration

For the sake of simplicity, we’ll see how the default HTTP Basic authentication is enabled using these frameworks.

Let’s start by looking at the dependencies and configuration we need to enable Security using Spring.

Spring requires both the standard spring-security-web and spring-security-config dependencies to set up Security in an application.

Next we need to add a class that extends the WebSecurityConfigurerAdapter and makes use of the @EnableWebSecurity annotation:

@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
 
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1")
            .password(passwordEncoder()
            .encode("user1Pass"))
          .authorities("ROLE_USER");
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .anyRequest().authenticated()
          .and()
          .httpBasic();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Here we’re using inMemoryAuthentication to set up the authentication.

Spring Boot also requires these dependencies to make it work, but we only need to define the dependency of spring-boot-starter-security as this will automatically add all the relevant dependencies to the classpath.

The security configuration in Spring Boot is the same as the one above.

To see how the JPA configuration can be achieved in both Spring and Spring Boot, we can check out our article A Guide to JPA with Spring.

7. Application Bootstrap

The basic difference in bootstrapping an application in Spring and Spring Boot lies with the servlet. Spring uses either the web.xml or SpringServletContainerInitializer as its bootstrap entry point.

On the other hand, Spring Boot uses only Servlet 3 features to bootstrap an application. Let’s talk about this in detail.

7.1. How Spring Bootstraps?

Spring supports both the legacy web.xml way of bootstrapping as well as the latest Servlet 3+ method.

Let’s see the web.xml approach in steps:

  1. Servlet container (the server) reads web.xml.
  2. The DispatcherServlet defined in the web.xml is instantiated by the container.
  3. DispatcherServlet creates WebApplicationContext by reading WEB-INF/{servletName}-servlet.xml.
  4. Finally, the DispatcherServlet registers the beans defined in the application context.

Here’s how Spring bootstraps using the Servlet 3+ approach:

  1. The container searches for classes implementing ServletContainerInitializer and executes.
  2. The SpringServletContainerInitializer finds all classes implementing WebApplicationInitializer.
  3. The WebApplicationInitializer creates the context with XML or @Configuration classes.
  4. The WebApplicationInitializer creates the DispatcherServlet with the previously created context.

7.2. How Spring Boot Bootstraps?

The entry point of a Spring Boot application is the class which is annotated with @SpringBootApplication:

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

By default, Spring Boot uses an embedded container to run the application. In this case, Spring Boot uses the public static void main entry point to launch an embedded web server.

It also takes care of the binding of the Servlet, Filter, and ServletContextInitializer beans from the application context to the embedded servlet container.

Another feature of Spring Boot is that it automatically scans all the classes in the same package or sub packages of the Main-class for components.

Additionally, Spring Boot provides the option of deploying it as a web archive in an external container. In this case, we have to extend the SpringBootServletInitializer:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    // ...
}

Here the external servlet container looks for the Main-class defined in the META-INF file of the web archive, and the SpringBootServletInitializer will take care of binding the Servlet, Filter, and ServletContextInitializer.

8. Packaging and Deployment

Finally, let’s see how an application can be packaged and deployed. Both of these frameworks support common package managing technologies like Maven and Gradle; however, when it comes to deployment, these frameworks differ a lot.

For instance, the Spring Boot Maven Plugin provides Spring Boot support in Maven. It also allows packaging executable jar or war archives and running an application “in-place.”

Some of the advantages of Spring Boot over Spring in the context of deployment include:

  • Provides embedded container support
  • Provision to run the jars independently using the command java -jar
  • Option to exclude dependencies to avoid potential jar conflicts when deploying in an external container
  • Option to specify active profiles when deploying
  • Random port generation for integration tests

9. Conclusion

In this article, we learned about the differences between Spring and Spring Boot.

In a few words, we can say that Spring Boot is simply an extension of Spring itself to make development, testing, and deployment more convenient.

Spring Boot @Configuration Properties_ Binding external configurations to POJO classes
06
Feb
2021

Spring Boot @ConfigurationProperties: Binding external configurations to POJO classes

External configurations allow you to work with the same code in different environments. They also provide you the flexibility to tune your application from a single place.

In this article, you’ll learn how to define and use external configurations in Spring Boot with a very simple annotation based API called @ConfigurationProperties.

@ConfigurationProperties bind external configurations to a strongly typed bean in your application code. You can inject and use this bean throughout your application code just like any other spring bean.

Let the exploring begin!

Creating the Application

Let’s create a sample application to learn how to define and use external configurations in spring boot.

We’ll use Spring Boot CLI to initialize the project. Fire up your terminal and type the following command to generate the project –

spring init --dependencies=web --name=config-properties-demo --package-name=com.example.demo config-properties-demo

Alternatively, You may also bootstrap the application from Spring Initializr website by following the instructions below –

  1. Go to http://start.spring.io
  2. Enter config-properties-demo in the Artifact field.
  3. Add Web in the dependencies section.
  4. Click Generate Project to download the project.

Following is the directory structure of the complete application for your reference-

Spring Boot Environment Based Configuration Properties Example

Defining Properties

Spring Boot application loads configuration properties from application.properties file located in the classpath by default.

Open src/main/resources/application.properties file and add the following properties to it

## Top level app properties
app.name=ConfigurationPropertiesDemoApp
app.description=${app.name} is a spring boot app that demonstrates how to use external configuration properties
app.upload-dir=/uploads

app.connect-timeout=500ms
app.read-timeout=10s

## Nested Object Properties (security)
app.security.username=user
app.security.password=123456
app.security.roles=USER,ADMIN,PARTNER   # List Property
app.security.enabled=true

## Map Properties (permissions)
app.security.permissions.CAN_VIEW_POSTS=true
app.security.permissions.CAN_EDIT_POSTS=true
app.security.permissions.CAN_DELETE_POSTS=false
app.security.permissions.CAN_VIEW_USERS=true
app.security.permissions.CAN_EDIT_USERS=true
app.security.permissions.CAN_DELETE_USERS=false

Binding external properties to a POJO class using @ConfigurationProperties

Let’s now see how we can bind the properties defined in the application.properties file to a POJO class using @ConfigurationProperties.

The @ConfigurationProperties annotation takes a prefix parameter, and binds all the properties with the specified prefix to the POJO class –

package com.example.demo.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;

import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String description;
    private String uploadDir;
    private Duration connectTimeout = Duration.ofMillis(1000);
    @DurationUnit(ChronoUnit.SECONDS)
    private Duration readTimeout = Duration.ofSeconds(30);
    private final Security security = new Security();

    // Getters and Setters (Omitted for brevity)

    public static class Security {
        private String username;
        private String password;
        private List<String> roles = new ArrayList<>();
        private boolean enabled;
        private Map<String, String> permissions = new HashMap<>();

        // Getters and Setters (Omitted for brevity)
    }
}

Let’s understand a few details about the binding:

  • Type-safe binding (List and Map)Notice how the comma separated roles in the properties file are bound to a List of roles and the permissions are bound to a Map.
  • Duration SupportAlso, note how the duration properties are safely bound to the Duration types. This is so awesome. Spring Boot allows you to specify durations with the following units in the application.properties files –
    • ns for nanoseconds
    • us for microseconds
    • ms for milliseconds
    • s for seconds
    • m for minutes
    • h for hours
    • d for days  
    The default unit is milliseconds. So if you don’t specify any unit in the properties file, It will be considered as milliseconds.Note that, you can also override the unit using @DurationUnit annotation as we have done in the above POJO class.
  • Naming ConventionAll the kebab case property names (ex: upload-dir) are bound to the corresponding camel case fields (ex: uploadDir) in the POJO class.Note that the properties can also be specified in camel case. But using kebab case is recommended.

Enabling Configuration Properties

You need to explicitly register the properties classes using the @EnableConfigurationProperties annotation as shown in the following example.

package com.example.demo;

import com.example.demo.config.AppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class ConfigPropertiesDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigPropertiesDemoApplication.class, args);
	}
}

Alternatively, you could also add a @Component annotation to the AppProperties class and the binding would still work.

Injecting Configuration Properties in your Spring Beans

The @ConfigurationProperties classes are regular spring beans, and you can inject them in the same way as any other bean.

In the following example, I’ve written a sample API that retrieves app details from configuration properties and returns them to the client –

package com.example.demo.controller;

import com.example.demo.config.AppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class IndexController {

    // Injecting ConfigurationProperties in your Beans
    @Autowired
    private AppProperties appProperties;

    @GetMapping("/")
    public Map<String, String> getAppDetails() {
        Map<String, String> appDetails = new HashMap<>();
        appDetails.put("name", appProperties.getName());
        appDetails.put("description", appProperties.getDescription());

        return appDetails;
    }
}

@ConfigurationProperties Validation

You can validate configuration properties using javax.validation constraints like @NotNull@NotEmpty etc.

To enable validation, you just need to add Spring’s @Validated annotation to the @ConfigurationProperties class –

package com.example.demo.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {
    @NotNull
    private String name;
    private String description;
    private String uploadDir;
    private Duration connectTimeout = Duration.ofMillis(1000);
    @DurationUnit(ChronoUnit.SECONDS)
    private Duration readTimeout = Duration.ofSeconds(30);
    @Valid
    private final Security security = new Security();

    // Getters and Setters (Omitted for brevity)

    public static class Security {
        private String username;
        private String password;
        @NotEmpty
        private List<String> roles = new ArrayList<>();
        private boolean enabled;
        private Map<String, String> permissions = new HashMap<>();

        // Getters and Setters (Omitted for brevity)
    }
}

Now, The Spring Boot application will throw a validation exception on startup, if the name property is null or the security.roles property is empty

Environment based (Profile specific) Configuration Properties

In addition to the standard application.properties file, Spring Boot also allows you to define profile-specific properties with the following naming convention –

application-{profile}.properties

The profile specific property files are loaded from the same location as the application.properties file, with profile-specific properties always overriding the default ones.

To illustrate this, Let’s define some profile-specific property files, and override some of the default properties –

  • application-dev.properties## Override properties for dev environment app.name=ConfigurationPropertiesDemoApp-DEVELOPMENT app.security.username=project-dev
  • application-staging.properties## Override properties for staging environment app.name=ConfigurationPropertiesDemoApp-STAGING app.security.username=project-staging app.security.password=C@ll1C0d3r
  • application-prod.properties## Override properties for prod environment app.name=ConfigurationPropertiesDemoApp-PRODUCTION app.security.username=project-prod app.security.password=C@ll1C0d3r

Now, we need to activate a spring profile so that the corresponding properties file is loaded by spring boot.

Activating a Spring Profile

You can set active profiles in many ways –

  1. Using application propertiesThe default application.properties file is always loaded by Spring Boot. You can set active profiles in the application.properties file by adding the following property –spring.profiles.active=staging After adding the above property, Spring Boot will load application-staging.properties file as well, and override properties with the new values specified there.
  2. Using command line argumentYou can set active profiles on startup by providing the spring.profiles.active command line argument like this –# Packaging the app mvn clean package -Dspring.profiles.active=staging # Running the packaged jar with `spring.profiles.active` argument java -jar -Dspring.profiles.active=staging target/config-properties-demo-0.0.1-SNAPSHOT.jar Moreover, Here is how you can set active profiles while running the application with spring-boot:run command –mvn spring-boot:run -Dspring.profiles.active=dev
  3. Using environment variableLastly, you can also set active profiles using the SPRING_PROFILES_ACTIVE environment variable-export SPRING_PROFILES_ACTIVE=prod

Running the application

Let’s run the application and access the sample Rest API to see configuration properties in action –

mvn spring-boot:run
$ curl http://localhost:8080
{"name":"ConfigurationPropertiesDemoApp","description":"ConfigurationPropertiesDemoApp is a spring boot app that demonstrates how to use external configuration properties"}

Running the application with active profiles set to prod

mvn spring-boot:run -Dspring.profiles.active=prod
$ curl http://localhost:8080
{"name":"ConfigurationPropertiesDemoApp-PRODUCTION","description":"ConfigurationPropertiesDemoApp-PRODUCTION is a spring boot app that demonstrates how to use external configuration properties"}

Conclusion

@ConfigurationProperties are a really nice way to bind external configurations in a type-safe manner. I use this feature in almost all my projects. Moreover, Spring Boot’s auto-configurations also rely on configuration properties.

Let me know what do you think about this feature in the comment section below.

JPA / Hibernate Composite Primary Key Example with Spring Boot
03
Mar
2021

JPA / Hibernate Composite Primary Key Example with Spring Boot

In this article, You’ll learn how to map a composite primary key in Hibernate using JPA’s @Embeddable and @EmbeddedId annotations.

Let’s say that We have an application that manages Employees of various companies. Every employee has a unique employeeId within his company. But the same employeeId can be present in other companies as well, So we can not uniquely identity an employee just by his employeeId.

To identify an employee uniquely, we need to know his employeeId and companyId both. Check out the following Employees table that contains a composite primary key which includes both the employeeId and companyId columns –

Hibernate Composite Primary Key Example Table Structure

Let’s create a project from scratch and learn how to map such composite primary key using JPA and Hibernate.

Creating the Project

You can generate the project quickly using Spring Boot CLI by typing the following command in the terminal –

spring init -n=jpa-composite-primary-key-demo -d=web,jpa,mysql --package-name=com.example.jpa jpa-composite-primary-key-demo

Alternatively, You can also use Spring Initializr web app to generate the project. Follow the instructions below to generate the app using Spring Initializr web app –

  1. Open http://start.spring.io
  2. Enter Artifact as “jpa-composite-primary-key-demo”
  3. Click Options dropdown to see all the options related to project metadata.
  4. Change Package Name to “com.example.jpa”
  5. Select WebJPA and Mysql dependencies.
  6. Click Generate to generate and download the project.

Following is the directory structure of the complete application for your reference –

JPA, Hibernate, Spring Boot Composite Primary Key Example Directory Structure

(Your bootstrapped project won’t have model and repository packages and all the other classes. We’ll create them as we proceed to next sections)

Configuring the Database and Hibernate Log Levels

Let’s add the MySQL database URL, username and password configurations in src/main/resources/application.properties file –

# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:mysql://localhost:3306/jpa_composite_pk_demo?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=root
spring.datasource.password=root

# Hibernate

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

Apart from MySQL database configurations, I’ve also specified hibernate log levels and other properties.

The property spring.jpa.hibernate.ddl-auto = update keeps the Entity types in your application and the mapped database tables in sync. Whenever you update a domain entity, the corresponding mapped table in the database will also get updated when you restart the application next time.

This is great for development because you don’t need to manually create or update the tables. They will automatically be created/updated based on the Entity classes in your application.

Before proceeding to the next section, Please make sure that you create a MySQL database named jpa_composite_pk_demo and change spring.datasource.username and spring.datasource.password properties as per your MySQL installation.

Defining the Domain model

A composite primary key is mapped using an Embeddable type in hibernate. We’ll first create an Embeddable type called EmployeeIdentity containing the employeeId and companyId fields, and then create the Employee entity which will embed the EmployeeIdentity type.

Create a new package named model inside com.example.jpa package and then add the following classes inside the model package –

1. EmployeeIdentity – Embeddable Type

package com.example.jpa.model;

import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;

@Embeddable
public class EmployeeIdentity implements Serializable {
    @NotNull
    @Size(max = 20)
    private String employeeId;

    @NotNull
    @Size(max = 20)
    private String companyId;

    public EmployeeIdentity() {

    }

    public EmployeeIdentity(String employeeId, String companyId) {
        this.employeeId = employeeId;
        this.companyId = companyId;
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public String getCompanyId() {
        return companyId;
    }

    public void setCompanyId(String companyId) {
        this.companyId = companyId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        EmployeeIdentity that = (EmployeeIdentity) o;

        if (!employeeId.equals(that.employeeId)) return false;
        return companyId.equals(that.companyId);
    }

    @Override
    public int hashCode() {
        int result = employeeId.hashCode();
        result = 31 * result + companyId.hashCode();
        return result;
    }
}

2. Employee – Domain model

package com.example.jpa.model;

import org.hibernate.annotations.NaturalId;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Email;
import javax.validation.constraints.Size;

@Entity
@Table(name = "employees")
public class Employee {

    @EmbeddedId
    private EmployeeIdentity employeeIdentity;

    @NotNull
    @Size(max = 60)
    private String name;

    @NaturalId
    @NotNull
    @Email
    @Size(max = 60)
    private String email;

    @Size(max = 15)
    @Column(name = "phone_number", unique = true)
    private String phoneNumber;

    public Employee() {

    }

    public Employee(EmployeeIdentity employeeIdentity, String name, String email, String phoneNumber) {
        this.employeeIdentity = employeeIdentity;
        this.name = name;
        this.email = email;
        this.phoneNumber = phoneNumber;
    }

    // Getters and Setters (Omitted for brevity)
}

In the Employee class, We use @EmbeddedId annotation to embed the EmployeeIdentity type and mark it as a primary key.

Creating the Repository

Next, Let’s create the repository for accessing the Employee data from the database. First, Create a new package named repository inside com.example.jpa package, then add the following interface inside the repository package –

package com.example.jpa.repository;

import com.example.jpa.model.Employee;
import com.example.jpa.model.EmployeeIdentity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, EmployeeIdentity> {

}

Code to test the Composite Primary Key Mapping

Finally, Let’s write some code to test the composite primary key mapping. Open the main class JpaCompositePrimaryKeyDemoApplication.java and replace it with the following code –

package com.example.jpa;

import com.example.jpa.model.Employee;
import com.example.jpa.model.EmployeeIdentity;
import com.example.jpa.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JpaCompositePrimaryKeyDemoApplication implements CommandLineRunner {

    @Autowired
    private EmployeeRepository employeeRepository;

    public static void main(String[] args) {
        SpringApplication.run(JpaCompositePrimaryKeyDemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // Cleanup employees table
        employeeRepository.deleteAllInBatch();

        // Insert a new Employee in the database
        Employee employee = new Employee(new EmployeeIdentity("E-123", "D-457"),
                "Yaniv Levy",
                "yaniv@fusebes.com",
                "+91-9999999999");

        employeeRepository.save(employee);
    }
}

We first clean up the Employee table and then insert a new Employee record with an employeeId and a companyId to test the setup.

You can run the application by typing mvn spring-boot:run from the root directory of the project. The Employee record will be inserted in the database once the application is successfully started.

Querying using the Composite Primary Key

Let’s now see some query examples using the composite primary key –

1. Retrieving an Employee using the composite primary key – (employeeId and companyId)

// Retrieving an Employee Record with the composite primary key
employeeRepository.findById(new EmployeeIdentity("E-123", "D-457"));

2. Retrieving all employees of a particular company

Let’s say that you want to retrieve all the employees of a company by companyId. For doing this, just add the following method in the EmployeeRepository interface.

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, EmployeeIdentity> {
    /* 
       Spring Data JPA will automatically parse this method name 
       and create a query from it
    */
    List<Employee> findByEmployeeIdentityCompanyId(String companyId);
}

That’s all! You don’t need to implement anything. Spring Data JPA will dynamically generate a query using the method name. You can use the above method in the main class to retrieve all the employees of a company like this –

// Retrieving all the employees of a particular company
employeeRepository.findByEmployeeIdentityCompanyId("D-457");

Conclusion

Congratulations guys! In this article, you learned how to implement a composite primary key in hibernate using @Embeddable and @EmbeddedId annotations.

Thanks for reading. See you in the next post.

Creating PDF with Java and iText
05
Mar
2021

Creating PDF with Java and iText

Java and PDF with iText. This article demonstrate how to create PDF files with Java and the iText library. In this tutorial iText version 5.0.x is used

iText is a Java library originally created by Bruno Lowagie which allows to create PDF, read PDF and manipulate them. The following tutorial will show how to create PDF files with iText. This tutorial assumes that you have basis in Java and Eclipse knowledge.

iText has a hierarchical structure. The smallest text unit is a “Chunk” which is a String with a pre-defined font. A “Phrase” combines several Chunks and allows to define line spacing. “Paragraph” is a subclass of “Phrase” and allows to define more layout attributes, e.g. margins. The class “Anchor” is a subclass of “Paragraph” and serves as the basis for hyperlinks in the generated PDF.

Create the following class “FirstPdf.java” . I assume that the code is pretty much self-explaining. I tried to add lots of comments to make it easier to understand. For more complex examples have a look at the iText Homepage.

package de.fusebes.itext.write;

import java.io.FileOutputStream;
import java.util.Date;

import com.itextpdf.text.Anchor;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chapter;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Section;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;


public class FirstPdf {
    private static String FILE = "c:/temp/FirstPdf.pdf";
    private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
            Font.BOLD);
    private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12,
            Font.NORMAL, BaseColor.RED);
    private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16,
            Font.BOLD);
    private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12,
            Font.BOLD);

    public static void main(String[] args) {
        try {
            Document document = new Document();
            PdfWriter.getInstance(document, new FileOutputStream(FILE));
            document.open();
            addMetaData(document);
            addTitlePage(document);
            addContent(document);
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // iText allows to add metadata to the PDF which can be viewed in your Adobe
    // Reader
    // under File -> Properties
    private static void addMetaData(Document document) {
        document.addTitle("My first PDF");
        document.addSubject("Using iText");
        document.addKeywords("Java, PDF, iText");
        document.addAuthor("Lars Vogel");
        document.addCreator("Lars Vogel");
    }

    private static void addTitlePage(Document document)
            throws DocumentException {
        Paragraph preface = new Paragraph();
        // We add one empty line
        addEmptyLine(preface, 1);
        // Lets write a big header
        preface.add(new Paragraph("Title of the document", catFont));

        addEmptyLine(preface, 1);
        // Will create: Report generated by: _name, _date
        preface.add(new Paragraph(
                "Report generated by: " + System.getProperty("user.name") + ", " + new Date(), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                smallBold));
        addEmptyLine(preface, 3);
        preface.add(new Paragraph(
                "This document describes something which is very important ",
                smallBold));

        addEmptyLine(preface, 8);

        preface.add(new Paragraph(
                "This document is a preliminary version and not subject to your license agreement or any other agreement with vogella.com ;-).",
                redFont));

        document.add(preface);
        // Start a new page
        document.newPage();
    }

    private static void addContent(Document document) throws DocumentException {
        Anchor anchor = new Anchor("First Chapter", catFont);
        anchor.setName("First Chapter");

        // Second parameter is the number of the chapter
        Chapter catPart = new Chapter(new Paragraph(anchor), 1);

        Paragraph subPara = new Paragraph("Subcategory 1", subFont);
        Section subCatPart = catPart.addSection(subPara);
        subCatPart.add(new Paragraph("Hello"));

        subPara = new Paragraph("Subcategory 2", subFont);
        subCatPart = catPart.addSection(subPara);
        subCatPart.add(new Paragraph("Paragraph 1"));
        subCatPart.add(new Paragraph("Paragraph 2"));
        subCatPart.add(new Paragraph("Paragraph 3"));

        // add a list
        createList(subCatPart);
        Paragraph paragraph = new Paragraph();
        addEmptyLine(paragraph, 5);
        subCatPart.add(paragraph);

        // add a table
        createTable(subCatPart);

        // now add all this to the document
        document.add(catPart);

        // Next section
        anchor = new Anchor("Second Chapter", catFont);
        anchor.setName("Second Chapter");

        // Second parameter is the number of the chapter
        catPart = new Chapter(new Paragraph(anchor), 1);

        subPara = new Paragraph("Subcategory", subFont);
        subCatPart = catPart.addSection(subPara);
        subCatPart.add(new Paragraph("This is a very important message"));

        // now add all this to the document
        document.add(catPart);

    }

    private static void createTable(Section subCatPart)
            throws BadElementException {
        PdfPTable table = new PdfPTable(3);

        // t.setBorderColor(BaseColor.GRAY);
        // t.setPadding(4);
        // t.setSpacing(4);
        // t.setBorderWidth(1);

        PdfPCell c1 = new PdfPCell(new Phrase("Table Header 1"));
        c1.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(c1);

        c1 = new PdfPCell(new Phrase("Table Header 2"));
        c1.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(c1);

        c1 = new PdfPCell(new Phrase("Table Header 3"));
        c1.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(c1);
        table.setHeaderRows(1);

        table.addCell("1.0");
        table.addCell("1.1");
        table.addCell("1.2");
        table.addCell("2.1");
        table.addCell("2.2");
        table.addCell("2.3");

        subCatPart.add(table);

    }

    private static void createList(Section subCatPart) {
        List list = new List(true, false, 10);
        list.add(new ListItem("First point"));
        list.add(new ListItem("Second point"));
        list.add(new ListItem("Third point"));
        subCatPart.add(list);
    }

    private static void addEmptyLine(Paragraph paragraph, int number) {
        for (int i = 0; i < number; i++) {
            paragraph.add(new Paragraph(" "));
        }
    }
}

The resulting pdf should look like the following.

pdfwrite10
Convert a String to Date (LocalDate, LocalDateTime, ZonedDateTime, LocalTime) in Java
03
Mar
2021

Convert a String to Date (LocalDate, LocalDateTime, ZonedDateTime, LocalTime) in Java

In this article, you’ll find several examples demonstrating how to convert a date represented as a String to a Date, LocalDate, LocalDateTime, ZonedDateTime, or LocalTime instance in Java.

How to convert a String to Date in Java using SimpleDateFormat

Dates are represented as Strings by using some patterns and symbols. Java’s SimpleDateFormat class uses the following patterns and symbols for parsing a String to Date.

SimpleDateFormat Date and Time Patterns

Let’s see an example:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatExample {
    public static void main(String[] args) {
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = "2020-01-31";

        try {
            // Parsing a String to Date
            Date date = dateFormatter.parse(dateStr);
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

Here is another example in which we parse a more complex date time representation:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatExample {
    public static void main(String[] args) {
        SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("E, MMM dd yyyy, hh:mm:ss a");
        String dateTimeStr = "Fri, Jan 31 2020, 10:30:45 PM";

        try {
            // Parse the String representation of date and time to Date
            Date date = dateTimeFormatter.parse(dateTimeStr);
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

Convert/Parse a String to LocalDate

We can also use the DateTime API introduced in Java 8 to convert a String to an instance of various DateTime classes like LocalDate, LocalTime, LocalDateTime, ZonedDateTime etc.

The DateTime API has a DateTimeFormatter class that can be used to define the date time format and parse the String according to the specified date time format. The DateTimeFormatter class uses the following patterns and symbols:

DateTimeFormatter Patterns and Symbols

Let’s see an example of parsing a String to LocalDate:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class LocalDateParseExample {
    public static void main(String[] args) {
        // Parse a String in ISO Date format (yyyy-MM-dd) to LocalDate
        LocalDate date1 = LocalDate.parse("2020-02-28");
        System.out.println(date1);

        // Parse a String in a custom date format to LocalDate using DateTimeFormatter
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        LocalDate date2 = LocalDate.parse("28/02/2020", dateFormatter);
        System.out.println(date2);

        // Parse a String in a custom date-time format to LocalDate using DateTimeFormatter
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("E, MMM dd yyyy, hh:mm:ss a");
        LocalDate date3 = LocalDate.parse("Fri, Feb 14 2020, 10:20:50 PM", dateTimeFormatter);
        System.out.println(date3);

    }
}

Convert/Parse a String to LocalDateTime

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeParseExample {
    public static void main(String[] args) {
        // Parse a String in ISO DateTime format (yyyy-MM-ddTHH:mm:ss) to LocalDateTime
        LocalDateTime dateTime1 = LocalDateTime.parse("2020-01-31T10:15:30");
        System.out.println(dateTime1);

        // Parse a String in a custom date format to LocalDate using DateTimeFormatter
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MMM dd yyyy, HH:mm");
        LocalDateTime dateTime2 = LocalDateTime.parse("Jan 11 2020, 10:30", dateTimeFormatter);
        System.out.println(dateTime2);

        // Parse a String in a custom DateTime format to LocalDateTime using DateTimeFormatter
        DateTimeFormatter descriptiveDateTimeFormatter = DateTimeFormatter.ofPattern("E, MMM dd yyyy, hh:mm:ss a");
        LocalDateTime dateTime3 = LocalDateTime.parse("Fri, Feb 14 2020, 10:20:50 PM", descriptiveDateTimeFormatter);
        System.out.println(dateTime3);

    }
}

Convert/Parse a String to LocalTime

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class LocalTimeParseExample {
    public static void main(String[] args) {
        // Parse a String in ISO Time format (HH:mm:ss) to LocalDate
        LocalTime time1 = LocalTime.parse("12:30:50");
        System.out.println(time1);

        // Parse a String in a custom date format to LocalTime using DateTimeFormatter
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
        LocalTime time2 = LocalTime.parse("28/02/2020 16:45:30", dateTimeFormatter);
        System.out.println(time2);

    }
}

Convert/Parse a String to ZonedDateTime

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class ZonedDateTimeParseExample {
    public static void main(String[] args) {
        // Parse a String in ISO DateTime format to ZonedDateTime
        ZonedDateTime dateTime1 = ZonedDateTime.parse("2020-01-31T10:15:30+01:00[Europe/Paris]");
        System.out.println(dateTime1);

        // Parse a String in a custom date time format to ZonedDateTime using DateTimeFormatter
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MMM dd yyyy, HH:mm (VV)");
        ZonedDateTime dateTime2 = ZonedDateTime.parse("Jan 11 2020, 10:30 (America/Los_Angeles)", dateTimeFormatter);
        System.out.println(dateTime2);
    }
}
Understanding Regular Expressions
18
Mar
2021

Understanding Regular Expressions

it’s time to get over your fears of regular expressions(regex)! If you’re like me, you’ve heard of regex but have always been confused by the cryptic syntax. Fear not, because in the next 5 minutes, you’ll have a basic understanding of what’s going on and how to use RegEx to make your life easier!

So what are Regular Expressions ?

Basically, regular expressions are patterns that you can use to find matching patterns in strings. This could be useful for password validation, or checking if the formatting of input fields is correct, or perhaps you want to parse a phone number, etc…

How do you use them?

There are a couple ways of creating a regex, you can either use the literal version( which I prefer) or you can use the constructor option. The literal version looks like so:

const regEx = /hello/;

When making a regular expression literal, you place the pattern between two forward slashes. Above, we would be searching for the word ‘hello’.

Using the constructor would look something like this:

 const regEx = new RegExp('hello');

I’m not the biggest fan of this, so moving forward I will only be using the literal version.

Testing Methods

How do you test your regex anyways? JavaScript provides us a couple of methods that are compatible with regular expressions:

  • test()
  • exec()
  • match()
  • matchAll()
  • replace()
  • search()
  • split()

For my examples I will primarily be using test() and match(). Test is a RegExp method used to search a string and return either true or false if your pattern is found, and match is a string method that can use regex and returns the instances found in an array.

How to Match Strings

As you saw in my example above, I created the regex /hello/. This pattern would be useful for finding the first case sensitive instance of ‘hello’. What if you want to find every instance of ‘hello’, case insensitive? This is where ‘flags’ come in.

Flags act as modifiers to your regular expression. They go after the closing slash and there are five native flags in JavaScript!

  • i : This makes your search case-insensitive!
  • g : This flag tells your search to look for all matches, not just the first one.
  • m : Multiline mode
  • s : This enables “dotall” mode. It allows ‘.’ to match newlines
  • u : Enables full unicode support
  • y : sticky; it matches only from the index indicated by the lastIndex property of the regex in the target string.

So if we wanted to find every instance of ‘hello’ case insensitive, in the string “Hello heLLO hellO HELLO!”, we would do something like this:

let regex = /hello/gi;
let string = “Hello heLLO hellO HELLO!”;
string.match(regex);//returns [ 'Hello', 'heLLO', 'hellO', 'HELLO' ]

See that’s not so bad! Let’s look at another tool that’s very useful: character classes.

Character Classes

Character classes let you match a group of characters by placing them inside square brackets! This lets you find multiple matches with different characters. For example: if you wanted to find the words ‘big’, ‘bag’, ‘bog’, ‘bug’ in the string “The big bug crawled out of my bag and went into the bog.” you could use a simple regular expression to do so!

let string = “The big bug crawled out of my bag and went into the bog.”;let regex = /b[aiou]g/gi;
string.match(regex);//returns [ 'big', 'bug', 'bag', 'bog' ]

That’s pretty cool. You can also search for a range of characters inside of a character set using a hyphen ‘-’! For example, if I wanted to find every number in a string for some reason, I could do something like this:

let string = "I want 6 chocolates, 5 pop tarts, and 3 pumpkin pies please."let regex = /[0-9]/g;
string.match(regex);//returns [ '6', '5', '3' ]

You can do the above and so, so much more using Regular Expressions. You’ll find it’s basically like another language! This is just the tip of the iceberg, and I hope at least I’ve made regex a little less scary. There is so much more to regular expressions than I can cover here, but there are plenty of great resources to continue learning.

Happy Coding!

Remove Duplicates from Sorted Array II
06
Feb
2021

Remove Duplicates from Sorted Array II

Remove Duplicates from Sorted Array II

Given a sorted array, remove the duplicates from the array in-place such that each element appears at most twice, and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example

Given array [1, 1, 1, 3, 5, 5, 7]

The output should be 6, with the first six elements of the array being [1, 1, 3, 5, 5, 7]

Remove Duplicates from Sorted Array II solution in Java

It can also be solved in O(n) time complexity by using two pointers (indexes).

class RemoveDuplicatesSortedArrayII {
  private static int removeDuplicates(int[] nums) {
    int n = nums.length;

    /*
     * This index will move when we modify the array in-place to include an element
     * so that it is not repeated more than twice.
     */
    int j = 0;

    for (int i = 0; i < n; i++) {
      /*
       * If the current element is equal to the element at index i+2, then skip the
       * current element because it is repeated more than twice.
       */
      if (i < n - 2 && nums[i] == nums[i + 2]) {
        continue;
      }

      nums[j++] = nums[i];
    }

    return j;
  }

  public static void main(String[] args) {
    int[] nums = new int[] { 1, 1, 1, 3, 5, 5, 7 };
    int newLength = removeDuplicates(nums);

    System.out.println("Length of array after removing duplicates = " + newLength);

    System.out.print("Array = ");
    for (int i = 0; i < newLength; i++) {
      System.out.print(nums[i] + " ");
    }
    System.out.println();
  }
}
# Output
Length of array after removing duplicates = 6
Array = 1 1 3 5 5 7 
Composite Primary Keys in JPA
14
May
2021

Composite Primary Keys in JPA

1. Introduction

In this tutorial, we’ll learn about Composite Primary Keys and the corresponding annotations in JPA.

2. Composite Primary Keys

A composite primary key – also called a composite key – is a combination of two or more columns to form a primary key for a table.

In JPA, we have two options to define the composite keys: The @IdClass and @EmbeddedId annotations.

In order to define the composite primary keys, we should follow some rules:

  • The composite primary key class must be public
  • It must have a no-arg constructor
  • It must define equals() and hashCode() methods
  • It must be Serializable

3. The IdClass Annotation

Let’s say we have a table called Account and it has two columns – accountNumber, accountType – that form the composite key. Now we have to map it in JPA.

As per the JPA specification, let’s create an AccountId class with these primary key fields:

public class AccountId implements Serializable {
    private String accountNumber;

    private String accountType;

    // default constructor

    public AccountId(String accountNumber, String accountType) {
        this.accountNumber = accountNumber;
        this.accountType = accountType;
    }

    // equals() and hashCode()
}

Next, let’s associate the AccountId class with the entity Account.

In order to do that, we need to annotate the entity with the @IdClass annotation. We must also declare the fields from the AccountId class in the entity Account and annotate them with @Id:

@Entity
@IdClass(AccountId.class)
public class Account {
    @Id
    private String accountNumber;

    @Id
    private String accountType;

    // other fields, getters and setters
}

4. The EmbeddedId Annotation

@EmbeddedId is an alternative to the @IdClass annotation.

Let’s consider another example where we have to persist some information of a Book with title and language as the primary key fields.

In this case, the primary key class, BookId, must be annotated with @Embeddable:

@Embeddable
public class BookId implements Serializable {
    private String title;
    private String language;

    // default constructor

    public BookId(String title, String language) {
        this.title = title;
        this.language = language;
    }

    // getters, equals() and hashCode() methods
}

Then, we need to embed this class in the Book entity using @EmbeddedId:

@Entity
public class Book {
    @EmbeddedId
    private BookId bookId;

    // constructors, other fields, getters and setters
}

5. @IdClass vs @EmbeddedId

As we just saw, the difference on the surface between these two is that with @IdClass, we had to specify the columns twice – once in AccountId and again in Account. But, with @EmbeddedId we didn’t.

There are some other tradeoffs, though.

For example, these different structures affect the JPQL queries that we write.

For example, with @IdClass, the query is a bit simpler:

SELECT account.accountNumber FROM Account account

With @EmbeddedId, we have to do one extra traversal:

SELECT book.bookId.title FROM Book book

Also, @IdClass can be quite useful in places where we are using a composite key class that we can’t modify.

Finally, if we’re going to access parts of the composite key individually, we can make use of @IdClass, but in places where we frequently use the complete identifier as an object, @EmbeddedId is preferred.

6. Conclusion

In this quick article, we explore composite primary keys in JPA.