英文:
java.lang.ClassCastException: org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass
问题
我有两个类,一个父类和一个子类,我使用了[这个][1]解决方法来定义混合继承策略,然而当使用maven编译时,我遇到了一个错误。
父类:
@Entity
@Table(name="ITEMS")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="ITEM_CATEGORY",discriminatorType=DiscriminatorType.INTEGER)
public class Item {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ITEM_ID")
protected Long itemId;
.
.
.}
子类:
@Entity
@SecondaryTable(name="TASKS", pkJoinColumns =
{@PrimaryKeyJoinColumn(name = "ITEM_ID", referencedColumnName = "ITEM_ID")})
@DiscriminatorValue(value=ItemCategory.Values.TASK)
public class Task extends Item {
//没有@Id字段}
错误:
java.lang.IllegalStateException: 无法加载应用程序上下文
Caused by: org.springframework.beans.factory.BeanCreationException: 在类路径资源[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]中定义的名为'entityManagerFactory'的bean创建时出错:初始化方法的调用失败;嵌套异常是java.lang.ClassCastException: 无法将org.hibernate.mapping.SingleTableSubclass转换为org.hibernate.mapping.RootClass
Caused by: java.lang.ClassCastException: 无法将org.hibernate.mapping.SingleTableSubclass转换为org.hibernate.mapping.RootClass
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- 从存储库查找父级 -->
</parent>
<dependencies>
<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-rest</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
DDL:
CREATE TABLE ITEMS(
ITEM_ID bigint 自增主键,
.
.
.
FOREIGN KEY(RELATED_TO_ITEM) 引用 ITEMS(ITEM_ID)
);
CREATE TABLE TASKS( #包括重复任务、一次性任务、学习任务和响应
ITEM_ID bigint 主键,
.
.
.
FOREIGN KEY(ITEM_ID) 引用 ITEMS(ITEM_ID)
);
[1]: https://stackoverflow.com/questions/1825676/changing-the-inheritance-strategy-in-branches-of-the-class-hierarchy-via-jpa-anno
英文:
I have 2 classes one parent and one child, I used this workaround to define mixed inheritance strategy, however when compiling with maven, I am getting an error.
Parent class:
@Entity
@Table(name="ITEMS")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="ITEM_CATEGORY",discriminatorType=DiscriminatorType.INTEGER)
public class Item {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ITEM_ID")
protected Long itemId;
.
.
.}
Child class:
@Entity
@SecondaryTable(name="TASKS", pkJoinColumns =
{@PrimaryKeyJoinColumn(name = "ITEM_ID", referencedColumnName = "ITEM_ID")})
@DiscriminatorValue(value=ItemCategory.Values.TASK)
public class Task extends Item {
//no @Id field}
error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.ClassCastException: org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass
Caused by: java.lang.ClassCastException: org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<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-rest</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
DDL:
CREATE TABLE ITEMS(
ITEM_ID bigint auto_increment primary key,
.
.
.
FOREIGN KEY(RELATED_TO_ITEM) references ITEMS(ITEM_ID)
);
CREATE TABLE TASKS( #INCLUDES REPEATED TASKS, ONETIME TASKS, LEARNING DUTY AND RESPONSES
ITEM_ID bigint primary key,
.
.
.
FOREIGN KEY(ITEM_ID) references ITEMS(ITEM_ID)
);
答案1
得分: 1
以下是您提供的内容的翻译部分:
我尝试使用您的映射(进行了轻微更改),确切地使用了您的Hibernate版本5.2.14.Final(spring-boot-starter-data-jpa 2.0.0.RELEASE):
表格:
CREATE TABLE ITEMS (
ITEM_ID bigint auto_increment primary key,
ITEM_CATEGORY bigint,
RELATED_TO_ITEM bigint,
FOREIGN KEY(RELATED_TO_ITEM) references ITEMS(ITEM_ID)
);
insert into ITEMS
values (1, 1, null), (2, 1, 1), (3, 0, 1), (4, 1, 2);
CREATE TABLE TASKS(
ITEM_ID bigint primary key,
code varchar(100),
FOREIGN KEY(ITEM_ID) references ITEMS(ITEM_ID)
);
insert into TASKS
values (1, 'TASK 1'), (2, 'Task 2'), (4, 'Task 4');
Hibernate映射:
@Entity
@Table(name = "ITEMS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="ITEM_CATEGORY", discriminatorType = DiscriminatorType.INTEGER)
public class Item
{
private Long itemId;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ITEM_ID")
public Long getItemId()
{
return itemId;
}
public void setItemId(Long itemId)
{
this.itemId = itemId;
}
}
@Entity
@SecondaryTable(name="TASKS", pkJoinColumns = {
@PrimaryKeyJoinColumn(name = "ITEM_ID", referencedColumnName = "ITEM_ID")
})
@DiscriminatorValue("1")
public class Task extends Item
{
private String code;
@Column(table = "TASKS", name = "code")
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
}
@Entity
@DiscriminatorValue("0")
public class Job extends Item
{
}
以及用于选择测试的简单代码:
List<Item> items = session.createQuery("select i from Item i", Item.class).getResultList();
将生成以下SQL:
/* select i from Item i */
select
item0_.ITEM_ID as ITEM_ID2_0_,
item0_1_.code as code1_1_,
item0_.ITEM_CATEGORY as ITEM_CAT1_0_
from DB_A.ITEMS item0_
left outer join DB_A.TASKS item0_1_ on item0_.ITEM_ID=item0_1_.ITEM_ID
以及插入测试:
Task task = new Task();
task.setCode("my new task 1");
session.persist(task);
将生成以下SQL:
/* insert com.sternkn.hibernate.model.Task */
insert into DB_A.ITEMS(ITEM_CATEGORY)
values (1)
/* insert com.sternkn.hibernate.model.Task */
insert into DB_A.TASKS(code, ITEM_ID)
values (?, ?)
英文:
I tried to use your mapping (with minor changes) with exactly your hibernate version 5.2.14.Final (spring-boot-starter-data-jpa 2.0.0.RELEASE):
Tables:
CREATE TABLE ITEMS (
ITEM_ID bigint auto_increment primary key,
ITEM_CATEGORY bigint,
RELATED_TO_ITEM bigint,
FOREIGN KEY(RELATED_TO_ITEM) references ITEMS(ITEM_ID)
);
insert into ITEMS
values (1, 1, null), (2, 1, 1), (3, 0, 1), (4, 1, 2);
CREATE TABLE TASKS(
ITEM_ID bigint primary key,
code varchar(100),
FOREIGN KEY(ITEM_ID) references ITEMS(ITEM_ID)
);
insert into TASKS
values (1, 'TASK 1'), (2, 'Task 2'), (4, 'Task 4');
Hibernate mapping:
@Entity
@Table(name = "ITEMS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="ITEM_CATEGORY", discriminatorType = DiscriminatorType.INTEGER)
public class Item
{
private Long itemId;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ITEM_ID")
public Long getItemId()
{
return itemId;
}
public void setItemId(Long itemId)
{
this.itemId = itemId;
}
}
@Entity
@SecondaryTable(name="TASKS", pkJoinColumns = {
@PrimaryKeyJoinColumn(name = "ITEM_ID", referencedColumnName = "ITEM_ID")
})
@DiscriminatorValue("1")
public class Task extends Item
{
private String code;
@Column(table = "TASKS", name = "code")
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
}
@Entity
@DiscriminatorValue("0")
public class Job extends Item
{
}
And simple code for select testing:
List<Item> items = session.createQuery("select i from Item i", Item.class).getResultList();
will generate the following sql:
/* select i from Item i */
select
item0_.ITEM_ID as ITEM_ID2_0_,
item0_1_.code as code1_1_,
item0_.ITEM_CATEGORY as ITEM_CAT1_0_
from DB_A.ITEMS item0_
left outer join DB_A.TASKS item0_1_ on item0_.ITEM_ID=item0_1_.ITEM_ID
And insert testing:
Task task = new Task();
task.setCode("my new task 1");
session.persist(task);
will generate the following sql:
/* insert com.sternkn.hibernate.model.Task */
insert into DB_A.ITEMS(ITEM_CATEGORY)
values (1)
/* insert com.sternkn.hibernate.model.Task */
insert into DB_A.TASKS(code, ITEM_ID)
values (?, ?)
If it will not help, please provide the full stack trace of your exception and full code of all entities from your inheritance hierarchy.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论