Java 休眠和继承(每个类的表)

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

我使用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.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