I will write the correction points when migrating the Spring Boot 1.5 application (about 7KL, SPA server part) to Spring Boot 2.0. A fair amount of modifications were needed, such as changing class packages and becoming Deprecated.
At first I didn't intend to set Spring Boot to 2.0, I just wanted to access Elasticsearch 6, but in order to access Elasticsearch 6, I have to increase spring-boot-starter-data-elasticsearch to 2.0 units. I had no choice but to raise Spring Boot itself to 2.0.
Maven
The application migrated this time depends on the following libraries.
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core-tiger</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
Originally I was using Spring IO platform, but EOL is September 2019, and "spring-boot-starter-parent" It is recommended to use it or import the spring-boot-dependencies bom. " Following the recommendation, I decided to change from Spring IO platform to spring-boot-starter-parent.
SpringBoot1.5
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Brussels-SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
SpringBoot2.0
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
The context-path hierarchy has changed. It seems to work as it is, but it is safer to change it.
SpringBoot1.5
server:
context-path: /sample
SpringBoot2.0
server:
servlet:
context-path: /sample
Since Spring Boot 2.0 is Java 8 compliant, the Adapter class, which implements the interface empty, has been deprecated and instead the default implementation of the method has been added to the interface itself. Therefore, the interface will be implemented directly instead of the Adapter extends.
SpringBoot1.5
public class WebMvcConfig extends WebMvcConfigurerAdapter {
SpringBoot2.0
public class WebMvcConfig implements WebMvcConfigurer {
SecurityAutoConfiguration, which is an Auto-configuration of security, was excluded in order to switch security settings depending on the profile, but this SecurityAutoConfiguration package has changed.
SpringBoot1.5
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
SpringBoot2.0
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
It seems that it has moved to the servlet package under the security package.
I was using ShaPasswordEncoder for the internal cache, but the class itself is gone. The class structure related to PasswordEncoder has been reviewed. Along with that, the ShaPasswordEncoder class and Md5PasswordEncoder class that use vulnerable algorithms have disappeared (although the algorithm itself seems to remain, it is [deprecated](https://info.michael-simons. eu / 2018/01/13 / spring-security-5-new-password-storage-format /)).
From Spring Boot 2.0, PasswordEncoder will be generated using PasswordEncoderFactories.
SpringBoot1.5
MessageDigestPasswordEncoder encoder = new ShaPasswordEncoder(256);
return encoder.encodePassword(password);
SpringBoot2.0
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
return encoder.encode(password);
The method has also changed from encodePassword () to encode ().
The hardest part of this fix was this (because there were so many ...). The findOne () method of CrudRepository has been renamed to findById (), and the return value is now an Optional type instead of an Entity type.
SpringBoot1.5
Employee employee = employeeRepository.findOne(employeeId);
SpringBoot2.0
Optional<Employee> employee = employeeRepository.findById(employeeId);
PageRequest new has been deprecated. Use of () instead.
SpringBoot1.5
employeeRepository.findAll(specifications,
new PageRequest(page, size, new Sort(
Sort.Direction.fromString(sortDirection), sortColumn)));
SpringBoot2.0
employeeRepository.findAll(specifications,
PageRequest.of(page, size, new Sort(
Sort.Direction.fromString(sortDirection), sortColumn)));
If you change PageRequest to of (), you should change Sort to of () to unify the style.
SpringBoot2.0
employeeRepository.findAll(specifications,
PageRequest.of(page, size, Sort.of(
Sort.Direction.fromString(sortDirection), sortColumn)));
With Java 8 adding a default implementation to the Specification interface, direct use of the Specifications class that implements the Specification interface has been deprecated. (Although the default implementation of the Specification interface uses the Specifications class.)
SpringBoot1.5
employeeRepository.findAll(
Specifications.where((root, query, cb) -> cb.equal(property, value)));
SpringBoot2.0
employeeRepository.findAll(
Specification.where((root, query, cb) -> cb.equal(property, value)));
There was also a change due to the Hibernate version going up to 5.2.17 with Spring Boot 2.0.
I used the ExplicitParameterInfo class when I wanted to explicitly specify NULL using Hibernate's NativeQuery, but the package of this class is from ʻorg.hibernate.jpa.criteria.compile.ExplicitParameterInfo to ʻorg.hibernate.query Changed to .criteria.internal.compile.ExplicitParameterInfo
.
** 2018/07/12 Addendum / Update ** In case of PostgreSQL 10, at least ExplicitParameterInfo can no longer be specified when specifying NULL. When I use ExplicitParameterInfo, I get an error like "ʻorg.postgresql.util.PSQLException: ERROR: Operator does not exist: text = by tea`". Therefore, if you want to specify a null type, use TypedParameterValue instead of ExplicitParameterInfo.
SpringBoot1.5
import org.hibernate.jpa.criteria.compile.ExplicitParameterInfo;
//Omission
Query query = entityManager.createNativeQuery(query);
query.setParameter(new ExplicitParameterInfo<>("employeeName", null, String.class), null);
List<Employee> employeeList = query.getResultList();
SpringBoot2.0
import org.hibernate.jpa.TypedParameterValue;
import org.hibernate.type.StringType;
//Omission
Query query = entityManager.createNativeQuery(query);
query.setParameter("employeeName", new TypedParameterValue(new StringType(), null));
List<Employee> employeeList = query.getResultList();
In this application, there was an implementation class of UserType that converts between JSONB column of PostgreSQL and String of Java. In Spring Boot 2.0 (Hibernate 5.2.17), the SessionImplementor class for the nullSafeGet / nullSafeSet argument is gone and is now a SharedSessionContractImplementor.
SpringBoot1.5
public class PostgresJsonType implements UserType {
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException {
//・ ・ ・
}
public void nullSafeSet(PreparedStatement st, Object value,
int index, SessionImplementor session)
throws HibernateException, SQLException {
//・ ・ ・
}
//・ ・ ・
}
SpringBoot2.0
public class PostgresJsonType implements UserType {
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
//・ ・ ・
}
public void nullSafeSet(PreparedStatement st, Object value,
int index, SharedSessionContractImplementor session)
throws HibernateException, SQLException {
//・ ・ ・
}
//・ ・ ・
}
This was originally badly implemented, but in application.yml
app:
function:
message-type:
AAA: xxx
BBB: yyy
When binding a value in ConfigurationProperties
@ConfigurationProperties(prefix = "app.function.messageType")
Like, it was possible to bind by referring to the chain case with camel case.
In Spring Boot 2.0, the check becomes strict, and if it is in the above state, an error will occur. (It is natural that an error will occur.)
Let's write in a chain case according to the definition properly. ..
@ConfigurationProperties(prefix = "app.function.message-type")
There are many changes that I didn't encounter in this migration. There is Spring Boot 2.0 Migration Guide on the official website, so please refer to it as well. ..
Recommended Posts