【发布时间】:2019-12-22 23:07:30
【问题描述】:
我有一个使用 Spring Data 的 Java Spring Boot 应用程序,一个 MySql 数据库, 以及我想使用 JOINED 继承策略在数据库中持久化的两个小类。
这里有一些代码:
pom 文件:
<?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>oli</groupId>
<artifactId>BugInheritanceBatch</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>BugInheritanceBatch</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
App 类:
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
BaseTable 实体:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BaseTable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private long value;
// getters and setters ...
}
子表实体:
@Entity
public class SubTable extends BaseTable {
private String name;
// getters and setters ...
}
DAO:
public interface BaseTableDao extends CrudRepository<BaseTable, Long> {
List<BaseTable> findAll();
}
使用此测试一切正常:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class BaseTableDaoTest {
@Autowired
private BaseTableDao dao;
@Test
public void test() {
SubTable item = new SubTable();
item.setName("name");
item.setValue(33);
item = dao.save(item);
// make sure our inserted item received an ID
Long id = item.getId();
Assert.assertNotNull(id);
// make sure we have 1 item in the table
List<BaseTable> items = dao.findAll();
Assert.assertEquals(1, items.size());
// make sure the item's type is correct and contains the expected values
Assert.assertTrue(items.get(0) instanceof SubTable);
SubTable insertedItem = (SubTable) items.get(0);
Assert.assertEquals((long) id, (long) insertedItem.getId());
Assert.assertEquals("name", insertedItem.getName());
Assert.assertEquals(33, insertedItem.getValue());
}
}
但是,如果我在 application.properties 中添加这一行:
spring.jpa.properties.hibernate.jdbc.batch_size=20
那么测试失败了
JpaSystemException: Cannot instantiate abstract class or interface: BaseTable...
经过一番调查并检查了数据库本身,我看到这个异常是由 dao.findAll() 语句引发的,因为 dao.save() 部分保存了实体(仅更新了 base_table,没有更新 sub_table)。此外,我得到了一个奇怪的 Hibernate 日志:
HHH000010: On release of batch it still contained JDBC statements
但是Hibernate记录的INSERT语句是正确的。
你有什么办法解决这个问题吗?
谢谢。
【问题讨论】:
标签: java mysql spring-boot spring-data