Skip to content

spring-boot-devtools dependency breaks hibernate with mysql 5.7 #7906

@zgulde

Description

@zgulde

Including the spring-boot-devtools and hibernate in the same project breaks hibernate with MySQL with the following exception:

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
	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:497)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.hibernate.PropertyAccessException: Could not set field value [5] value by reflection : [class com.example.SomeTable.id] setter of com.example.SomeTable.id
	at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:58)
	at org.hibernate.tuple.entity.AbstractEntityTuplizer.setIdentifier(AbstractEntityTuplizer.java:259)
	at org.hibernate.persister.entity.AbstractEntityPersister.setIdentifier(AbstractEntityPersister.java:4667)
	at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:87)
	at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:623)
	at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:277)
	at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258)
	at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:303)
	at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
	at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
	at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
	at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
	at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
	at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:674)
	at org.hibernate.internal.SessionImpl.save(SessionImpl.java:666)
	at org.hibernate.internal.SessionImpl.save(SessionImpl.java:661)
	at com.example.DevtoolsHibernateBugApplication.main(DevtoolsHibernateBugApplication.java:19)
	... 5 more
Caused by: java.lang.IllegalArgumentException: Can not set long field com.example.SomeTable.id to com.example.SomeTable
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
	at sun.reflect.UnsafeLongFieldAccessorImpl.set(UnsafeLongFieldAccessorImpl.java:75)
	at java.lang.reflect.Field.set(Field.java:764)
	at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:38)
	... 25 more

see sample application PR

When the spring-boot-devtools dependency is removed, everything works as intended.

Please let me know if I can provide any additional information.

MySQL version

mysql Ver 14.14 Distrib 5.7.16, for osx10.10 (x86_64) using EditLine wrapper

Java version

java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

The following is a minimal bug reproduction

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>devtools-hibernate-bug</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>devtools-hibernate-bug</name>
	<description>minimal reproduction of spring boot devtools - hibernate clash</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.BUILD-SNAPSHOT</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>
</project>

hibernate.cfg.xml

<?xml version="1.0"?>
<!DOCTYPE
        hibernate-configuration
        PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"
        >
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="connection.url">
            jdbc:mysql://localhost/test_db?createDatabaseIfNotExist=true
        </property>
        <property name="connection.username">root</property>
        <property name="connection.password">pass</property>
        <property name="show_sql">true</property>
        <mapping class="com.example.SomeTable"/>
    </session-factory>
</hibernate-configuration>

application.properties

spring.datasource.url=jdbc:mysql://localhost/test_db?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=pass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

SomeTable.java

package com.example;

import javax.persistence.*;

@Entity
@Table(name = "some_table")
public class SomeTable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
}

DevtoolsHibernateBugApplication.java

package com.example;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

		Session session = getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		session.save(new SomeTable());
        tx.commit();
    }

    private static SessionFactory getSessionFactory() {
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
            .configure()
            .build();

        return new MetadataSources(registry)
            .buildMetadata()
            .buildSessionFactory();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions