[JAVA] Was ich bei der Migration von der Spring Boot 1.5-Serie zur 2.0-Serie getan habe

Einführung

Wir haben SpringBoot 2.0.2 aktualisiert. Für Projekte, die Kotlin in [hier] unterstützen (https://qiita.com/Yuki10/items/3dd563b76dceebbe154b). Hier werde ich über die Arbeit schreiben, die zu dieser Zeit stattgefunden hat.

Da dieses Projekt als Server für die REST-API ausgeführt wird, konnten wir auch die Migration von Thymeleaf vermeiden. Ich migriere ein Spring MVC-Projekt separat, daher werde ich separat darüber schreiben.

Ich habe hauptsächlich auf die folgenden Websites und Artikel verwiesen.

Zunächst ein Upgrade von Spring Boot

Ändern Sie pom.xml, um die Version von Spring Boot zu aktualisieren.

Auszug aus Änderungen

pom.xml


    <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
 -    <version>1.5.8.RELEASE</version>
 +    <version>2.0.2.RELEASE</version>
      <relativePath />
    </parent>

・ ・ ・

      <dependency>
        <!-- https://docs.spring.io/spring-session/docs/current/reference/html5/guides/java-redis.html -->
        <groupId>org.springframework.session</groupId>
 -      <artifactId>spring-session</artifactId>
 +      <artifactId>spring-session-data-redis</artifactId>
      </dependency>

・ ・ ・

      <!-- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide#jackson--json-support -->
 +    <dependency>
 +      <groupId>org.springframework.boot</groupId>
 +      <artifactId>spring-boot-starter-json</artifactId>
 +    </dependency>

・ ・ ・
      <!-Ursprünglich habe ich Hikari PC verwendet, also habe ich die Abhängigkeit gelöscht-->
      <!-- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide#configuring-a-datasource -->
 -    <dependency>
 -      <groupId>com.zaxxer</groupId>
 -      <artifactId>HikariCP</artifactId>
 -    </dependency>

・ ・ ・

      <!--Hier nach dem Testen löschen->
      <!-- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide#before-you-start -->
 +    <dependency>
 +      <groupId>org.springframework.boot</groupId>
 +      <artifactId>spring-boot-properties-migrator</artifactId>
 +      <scope>runtime</scope>
 +    </dependency>

Vermeiden Sie die Verwendung des WebMvcConfigurerAdapter der Application-Klasse

- public class XxxApplication extends WebMvcConfigurerAdapter {
+ public class XxxApplication implements WebMvcConfigurer{

Build-> Fix-> Rebuild

Nachdem Sie pom.xml eingestellt haben, erstellen Sie die Änderung und wiederholen Sie sie.

Kompilierungsfehler in findOne des JPA-Repositorys

Zunächst ist der folgende Fehler aufgetreten.

Error:(41, 41) Kotlin: Type inference failed: fun <S : #{Tabellenname}!> findOne(p0: Example<S!>!): Optional<S!>!
cannot be applied to
(Long)
Error:(41, 49) Kotlin: Type mismatch: inferred type is Long but Example<(???..???)>! was expected

Dies ist auf eine Änderung der Spring Data CRUD-Methode zurückzuführen. https://spring.io/blog/2017/06/20/a-preview-on-spring-data-kay#improved-naming-for-crud-repository-methods

Ändern Sie den Fehler in der ersten Zeile von "findOne" in "findById". Der Fehler in der zweiten Zeile lautet "get" von "Optional", da der Rückgabewert von "findById" "Java Optional" ist.

In ähnlicher Weise haben sich die Argumente für "Speichern" und "Löschen" von denen, die "Liste" übergeben, zu denen geändert, die "Entität" übergeben. Rufen Sie stattdessen die Methoden "saveAll" und "deleteAll" auf. Wenn nur ein Datensatz betroffen ist, ist es natürlich besser, "Speichern" und "Löschen" zu verwenden. Informieren Sie sich daher über die für die Migration verfügbare Zeit.

ConfigureRedisAction kann nicht aufgelöst werden

Error:(13, 53) java:Paket org.springframework.session.data.redis.Konfiguration existiert nicht

Obwohl die Reihenfolge nicht in Ordnung ist, konnte ConfigureRedisAction mit der folgenden Definition für die Verwendung von ElastiCache nicht aufgelöst werden. Dies liegt daran, dass es in ein Paket namens "spring-session-data-redis" ausgeschnitten wurde.

https://docs.spring.io/spring-session/docs/current/reference/html5/guides/java-redis.html

	@Bean
	public static ConfigureRedisAction configureRedisAction() {
		return ConfigureRedisAction.NO_OP;
	}

Die Änderungen finden Sie im Teil "Frühlingssitzung" von "pom.xml". Außerdem habe ich die "Salat" -Abhängigkeit nicht hinzugefügt, da "Spring-Boot-Starter-Daten-Redis" ursprünglich in der Abhängigkeit enthalten war.

Veraltet wie org.hibernate.validator.constraints.NotBlank

In diesem Sinne haben wir es durch "javax.validation.constraints.NotEmpty" usw. ersetzt.

Fehler bei der automatischen Konfiguration von jdbc

Error:(7, 51) java:Symbol kann nicht gefunden werden
Symbol:Klasse DataSourceBuilder
Ort:Paket org.springframework.boot.autoconfigure.jdbc

Dies schien zu passieren, weil ich mit mehreren Datenquellen arbeitete.

application.properties


hoge.datasource.driver-class-name        = com.mysql.jdbc.Driver
hoge.datasource.url                    = jdbc:mysql://127.0.0.1:33306/hoge
hoge.datasource.username                = hoge
hoge.datasource.password                = fuga
#Andere weggelassen
#Über x für mehrere Datenquellen

Ursprünglich wurde es wie folgt eingestellt

HogeDatabaseConfig.java


 @Configuration
 @EnableTransactionManagement
 @EnableJpaRepositories(entityManagerFactoryRef = "hogeEntityManagerFactory", transactionManagerRef = "hogeTransactionManager", basePackages = {
 		"jp.xxx.data.hoge.repository" })
 public class HogeDatabaseConfig extends AbstractDatabaseConfig {
 
 	@Bean(name = "hogeDataSource")
	@ConfigurationProperties(prefix = "hoge.datasource")
 	public DataSource hogeDataSource() {
		return DataSourceBuilder.create().build();
 	}
 
 	@Bean(name = "hogeEntityManagerFactory")
	public LocalContainerEntityManagerFactoryBean hogeEntityManagerFactory(EntityManagerFactoryBuilder builder,
		return builder.dataSource(hogeDataSource)
		        .packages("jp.xxx.data.hoge.entity").persistenceUnit("hoge")
				.properties(buildProperties()).build();
 	}
 
 	@Bean(name = "hogeTransactionManager")
 	public PlatformTransactionManager hogeTransactionManager(
 			@Qualifier("hogeEntityManagerFactory") EntityManagerFactory hogeEntityManagerFactory) {
 		return new JpaTransactionManager(hogeEntityManagerFactory);
 	}
 }

Ich habe es jedoch wie folgt behoben. Ich denke, es gibt einen besseren Weg, diesen Teil zu tun.

HogeDatabaseConfig.java


 @Configuration
 @ConfigurationProperties(prefix = "hoge.datasource")
 @EnableTransactionManagement
 @EnableJpaRepositories(entityManagerFactoryRef = "hogeEntityManagerFactory", transactionManagerRef = "hogeTransactionManager", basePackages = {
 		"jp.xxx.data.hoge.repository" })
 public class HogeDatabaseConfig extends AbstractDatabaseConfig {
 
	@Autowired
	private Environment env;

 	@Bean(name = "hogeDataSource")
 	public DataSource hogeDataSource() {
		final DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(env.getProperty("hoge.datasource.driver-class-name"));
		dataSource.setUrl(env.getProperty("hoge.datasource.url"));
		dataSource.setUsername(env.getProperty("hoge.datasource.username"));
		dataSource.setPassword(env.getProperty("hoge.datasource.password"));
		return dataSource;
 	}
 
 	@Bean(name = "hogeEntityManagerFactory")
	public EntityManagerFactory hogeEntityManagerFactory(
 			@Qualifier("hogeDataSource") DataSource hogeDataSource) {
		final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
		factoryBean.setDataSource(hogeDataSource);
		factoryBean.setPersistenceUnitName("hoge");
		factoryBean.setPackagesToScan("jp.xxx.data.hoge.entity");
		factoryBean.setJpaPropertyMap(buildProperties());
		factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
		factoryBean.afterPropertiesSet();
		return factoryBean.getNativeEntityManagerFactory();
 	}
 
 	@Bean(name = "hogeTransactionManager")
 	public PlatformTransactionManager hogeTransactionManager(
 			@Qualifier("hogeEntityManagerFactory") EntityManagerFactory hogeEntityManagerFactory) {
 		return new JpaTransactionManager(hogeEntityManagerFactory);
 	}
 }

Tomcat beginnt hier

Obwohl Tomcat gestartet wurde, floss das folgende Fehlerprotokoll.

java.lang.ClassCastException: jp.xxx.service.HogeService$Fuga cannot be cast to org.springframework.core.io.support.ResourceRegion
	at org.springframework.http.converter.ResourceRegionHttpMessageConverter.writeResourceRegionCollection(ResourceRegionHttpMessageConverter.java:182)
	at org.springframework.http.converter.ResourceRegionHttpMessageConverter.writeInternal(ResourceRegionHttpMessageConverter.java:139)
	at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102)
	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:272)
	at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180)
	at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)

Es scheint, dass es auftritt, weil PostgreSQL auch in der Datenquelle ist.

Dies wurde vermieden, indem "hibernate.properties" erstellt und platziert wurden.

hibernate.properties


hibernate.jdbc.lob.non_contextual_creation = true

Bis zu diesem Zeitpunkt ist zum Zeitpunkt des Starts kein Fehler aufgetreten.

Plötzliche ClassCastException

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method jp.xxx.controller.HogeController.createFuga, parameter form
	at jp.xxx.controller.HogeController.createCampaign(HogeController.kt)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Entspricht durch Konvertieren des Argumenttyps "Form" von "HogeForm" in den nullbaren Typ "HogeForm".

Fehler bei der Konvertierung des Datumstyps

Failed to convert value of type 'java.lang.String[]' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2018-06-11T00:00:00'; nested exception is java.lang.IllegalArgumentException

Ich war ein wenig süchtig nach diesem Teil und die Ursache war nicht klar, aber es funktionierte, indem das Objekt, das die Daten von der Kotlin-Datenklasse empfing, in eine normale Kotlin-Klasse geändert wurde.

Wenn es sich um PUT handelt, wird der Wert des Formulars nicht übergeben

Ich hatte keine Zeit, die Ursache zu untersuchen, also habe ich den PUT-Teil in POST umgeschrieben ...

Wenn der Rückgabetyp des REST-Controllers "List " ist, kann er nicht in JSON konvertiert werden, und es tritt ein Fehler auf.

Ich habe vergessen, das Fehlerprotokoll zu nehmen.

Ursprünglich eine solche Implementierung Kehren Sie zunächst nicht mit List zurück ...

    @GetMapping("/hoge")
    public List<Object> hoge() {
        return hogeService.hoges();
    }

Da der Rückgabetyp ziemlich kompliziert war, habe ich ihn auf der Controllerseite zu JSON gemacht und zurückgegeben.

    @GetMapping("/hoge")
    public String hoge() throws JsonProcessingException {
        final List<Object> hoges = hogeService.hoges();
        final ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(hoges);
    }

Damit ist die Migration abgeschlossen und die Migration abgeschlossen.

Recommended Posts