Java 休眠和继承(每个类的表)
我使用Hibernate来持久化继承的对象,但我在尝试持久化数据库中的对象时收到了以下消息:Java 休眠和继承(每个类的表),java,hibernate,inheritance,orm,annotations,Java,Hibernate,Inheritance,Orm,Annotations,我使用Hibernate来持久化继承的对象,但我在尝试持久化数据库中的对象时收到了以下消息: org.springframework.dao.InvalidDataAccessResourceUsageException: Could not execute JDBC batch update; SQL [update Widget set CONTAINER_ID=? where WIDGET_ID=?]; nested exception is org.hibernate.exceptio
org.springframework.dao.InvalidDataAccessResourceUsageException: Could not execute
JDBC batch update; SQL [update Widget set CONTAINER_ID=? where WIDGET_ID=?]; nested
exception is org.hibernate.exception.SQLGrammarException:
Could not execute JDBC batch update (...) Caused by: java.sql.BatchUpdateException: Table
'schema.widget' doesn't exist
以下是我用来生成表的类:
@Entity
@Table(name="CONTAINER")
public class Container {
(...)
private Set<Widget> widgets;
@OneToMany(targetEntity = Widget.class)
@JoinColumn(name="CONTAINER_ID", nullable=true)
public Set<Widget> getWidgets() {
return widgets;
}
public void setWidgets(Set<Widget> widgets) {
this.widgets = widgets;
}
}
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Widget {
private long id;
private int position;
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name="WIDGET_ID")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name="POSITION")
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}
@Entity
@Table(name="TEXT_WIDGET")
public class TextWidget extends Widget {
(...)
}
@Entity
@Table(name="IMAGE_WIDGET")
public class ImageWidget extends Widget {
(...)
}
@实体
@表(name=“CONTAINER”)
公营货柜{
(...)
私有集合小部件;
@OneToMany(targetEntity=Widget.class)
@JoinColumn(name=“CONTAINER\u ID”,nullable=true)
公共集合getWidgets(){
返回窗口小部件;
}
公共void集合小部件(集合小部件){
this.widgets=widgets;
}
}
@实体
@继承(策略=继承类型。每个类的表)
公共抽象类小部件{
私人长id;
私人职位;
@身份证
@GeneratedValue(策略=GenerationType.TABLE)
@列(name=“WIDGET\u ID”)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@列(name=“POSITION”)
public int getPosition(){
返回位置;
}
公共无效设置位置(内部位置){
这个位置=位置;
}
}
@实体
@表(name=“TEXT\u小部件”)
公共类TextWidget扩展小部件{
(...)
}
@实体
@表(name=“IMAGE\u小部件”)
公共类ImageWidget扩展小部件{
(...)
}
这意味着Hibernate正在寻找表“widget”,但它没有被创建,这是有意义的,因为我选择了InheritanceType.table\u PER\u CLASS选项,然后只有具体的类才有表。在数据库中,我可以看到容器、文本窗口小部件和图像窗口小部件表
然后,当我尝试执行此代码并保存容器时,出现了上述错误:
Set<Widget> widgets = new HashSet<Widget>();
widgets.add(textw1); // instance of TextWidget
widgets.add(imgw1); // instance of ImageWidget
Container container1 = new Container();
container1.setWidgets(widgets);
Set widgets=newhashset();
widgets.add(textw1);//TextWidget的实例
widgets.add(imgw1);//ImageWidget的实例
Container container1=新容器();
container1.setWidgets(小部件);
谢谢你的帮助 您的关联必须是双向的,如Hibernate文档中所述 这种策略有许多缺点(尤其是。 使用多态查询和 协会)在JPA中解释 规范,Hibernate参考 文档,Hibernate正在运行, 还有很多其他地方。冬眠工作 他们中的大多数人都在实施这一计划 使用SQL联合查询的策略。信息技术 通常用于 继承层次结构:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable { ... }
此策略支持一对多
关联,前提是
双向。这一策略确实有效
不支持标识生成器
策略:必须共享id
隔着几张桌子。因此,,
使用此策略时,您应该
不使用自动或身份
这样,Hibernate将能够在每个具体的小部件表中创建适当的外键列。这是一个实际有效的映射。对于容器
:
@Entity
public class Container {
@Id @GeneratedValue
private long id;
@OneToMany(targetEntity = Widget.class, mappedBy = "container", cascade = CascadeType.ALL)
private Set<Widget> widgets = new HashSet<Widget>();
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public Set<Widget> getWidgets() { return widgets; }
public void setWidgets(Set<Widget> widgets) { this.widgets = widgets; }
public void addToWidgets(Widget widget) {
this.getWidgets().add(widget);
widget.setContainer(this);
}
public void removeFromWidgets(Widget widget) {
this.getWidgets().remove(widget);
widget.setContainer(null);
}
}
以下测试方法(在事务内部运行)刚刚通过:
@Test
public void testInsertContainer() {
TextWidget textw1 = new TextWidget();
ImageWidget imgw1 = new ImageWidget();
Container container1 = new Container();
container1.addToWidgets(textw1); // instance of TextWidget
container1.addToWidgets(imgw1); // instance of ImageWidget
session.persist(container1);
session.flush();
assertNotNull(textw1.getId());
assertNotNull(imgw1.getId());
assertNotNull(container1.getId());
}
并生成以下SQL:
21:59:57.964 [main] DEBUG org.hibernate.SQL - select next_hi from hibernate_unique_key for read only with rs
21:59:57.978 [main] DEBUG org.hibernate.SQL - update hibernate_unique_key set next_hi = ? where next_hi = ?
21:59:58.063 [main] DEBUG org.hibernate.SQL - null
21:59:58.125 [main] DEBUG org.hibernate.SQL - insert into Container (id) values (?)
Hibernate: insert into Container (id) values (?)
21:59:58.140 [main] TRACE org.hibernate.type.LongType - binding '98304' to parameter: 1
21:59:58.145 [main] DEBUG org.hibernate.SQL - insert into ImageWidget (container_id, position, id) values (?, ?, ?)
Hibernate: insert into ImageWidget (container_id, position, id) values (?, ?, ?)
21:59:58.164 [main] TRACE org.hibernate.type.LongType - binding '98304' to parameter: 1
21:59:58.165 [main] TRACE org.hibernate.type.IntegerType - binding '0' to parameter: 2
21:59:58.166 [main] TRACE org.hibernate.type.LongType - binding '32768' to parameter: 3
21:59:58.172 [main] DEBUG org.hibernate.SQL - insert into TextWidget (container_id, position, id) values (?, ?, ?)
Hibernate: insert into TextWidget (container_id, position, id) values (?, ?, ?)
21:59:58.187 [main] TRACE org.hibernate.type.LongType - binding '98304' to parameter: 1
21:59:58.188 [main] TRACE org.hibernate.type.IntegerType - binding '0' to parameter: 2
21:59:58.189 [main] TRACE org.hibernate.type.LongType - binding '32769' to parameter: 3
21:59:57.964[main]DEBUG org.hibernate.SQL-从hibernate\u unique\u键中选择next\u hi,用于rs只读
21:59:57.978[main]DEBUG org.hibernate.SQL-更新hibernate_unique_key set next_hi=?下一步在哪里?
21:59:58.063[main]DEBUG org.hibernate.SQL-空
21:59:58.125[main]DEBUG org.hibernate.SQL-插入容器(id)值(?)
休眠:插入容器(id)值(?)
21:59:58.140[main]TRACE org.hibernate.type.LongType-将“98304”绑定到参数:1
21:59:58.145[main]DEBUG org.hibernate.SQL-插入ImageWidget(容器id、位置、id)值(?,,?)
Hibernate:插入ImageWidget(容器id、位置、id)值(?、、?)
21:59:58.164[main]TRACE org.hibernate.type.LongType-将“98304”绑定到参数:1
21:59:58.165[main]TRACE org.hibernate.type.IntegerType-将“0”绑定到参数:2
21:59:58.166[main]TRACE org.hibernate.type.LongType-将“32768”绑定到参数:3
21:59:58.172[main]DEBUG org.hibernate.SQL-插入TextWidget(容器id、位置、id)值(?,,?)
Hibernate:插入TextWidget(容器id、位置、id)值(?,?)
21:59:58.187[main]TRACE org.hibernate.type.LongType-将“98304”绑定到参数:1
21:59:58.188[main]TRACE org.hibernate.type.IntegerType-将“0”绑定到参数:2
21:59:58.189[main]TRACE org.hibernate.type.LongType-将“32769”绑定到参数:3
但是请记住,每个类的表策略对多态关系的支持很差,如果您有许多小部件子项,则可能根本不合适(这将导致巨大的SQL联合)
相关问题
21:59:57.964 [main] DEBUG org.hibernate.SQL - select next_hi from hibernate_unique_key for read only with rs
21:59:57.978 [main] DEBUG org.hibernate.SQL - update hibernate_unique_key set next_hi = ? where next_hi = ?
21:59:58.063 [main] DEBUG org.hibernate.SQL - null
21:59:58.125 [main] DEBUG org.hibernate.SQL - insert into Container (id) values (?)
Hibernate: insert into Container (id) values (?)
21:59:58.140 [main] TRACE org.hibernate.type.LongType - binding '98304' to parameter: 1
21:59:58.145 [main] DEBUG org.hibernate.SQL - insert into ImageWidget (container_id, position, id) values (?, ?, ?)
Hibernate: insert into ImageWidget (container_id, position, id) values (?, ?, ?)
21:59:58.164 [main] TRACE org.hibernate.type.LongType - binding '98304' to parameter: 1
21:59:58.165 [main] TRACE org.hibernate.type.IntegerType - binding '0' to parameter: 2
21:59:58.166 [main] TRACE org.hibernate.type.LongType - binding '32768' to parameter: 3
21:59:58.172 [main] DEBUG org.hibernate.SQL - insert into TextWidget (container_id, position, id) values (?, ?, ?)
Hibernate: insert into TextWidget (container_id, position, id) values (?, ?, ?)
21:59:58.187 [main] TRACE org.hibernate.type.LongType - binding '98304' to parameter: 1
21:59:58.188 [main] TRACE org.hibernate.type.IntegerType - binding '0' to parameter: 2
21:59:58.189 [main] TRACE org.hibernate.type.LongType - binding '32769' to parameter: 3