2009-04-28 26 views
2

我有一个简单的类层次结构,我试图使用Hibernate/JPA。在2个表中拆分休眠实体

基本上我想要的是MovementData在它自己的表中有一个FK到数据库中主车辆表的整数ID。

我做错了什么?我还能如何完成类似的事情? 我很确定我遵循JPA规范。 (EJB3在行动说,这应该工作:EJB3 In Action: @SecondaryTable

这里是我得到异常的一部分:

SEVERE: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) 
org.hibernate.AssertionFailure: Table MOVEMENT_DATA not found 
    at org.hibernate.persister.entity.JoinedSubclassEntityPersister.getTableId(JoinedSubclassEntityPersister.java:480) 
    at org.hibernate.persister.entity.JoinedSubclassEntityPersister.<init>(JoinedSubclassEntityPersister.java:259) 
    at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:87) 
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:261) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327) 

下面是一些从休眠,涉及到车辆中的登录信息的...它看起来是承认一切很好..然后,它会因某种原因除外。

INFO: Binding entity from annotated class: com.dataobject.Vehicle 
FINE: Import with entity name Vehicle 
INFO: Bind entity com.dataobject.Vehicle on table VEHICLE 
INFO: Adding secondary table to entity com.dataobject.Vehicle -> MOVEMENT_DATA 
FINE: Processing com.dataobject.Vehicle property annotation 
FINE: Processing annotations of com.dataobject.Vehicle.id 
FINE: Binding column id. Unique false. Nullable false. 
FINE: id is an id 
FINE: building SimpleValue for id 
FINE: Building property id 
FINEST: Cascading id with null 
FINE: Bind @Id on id 
FINE: Processing annotations of com.dataobject.Vehicle.color 
FINE: Binding column COLOR. Unique false. Nullable true. 
FINE: binding property color with lazy=false 
FINE: building SimpleValue for color 
FINE: Building property color 
FINEST: Cascading color with null 
FINE: Processing annotations of com.dataobject.Vehicle.movementData 
FINE: Binding column movementData. Unique false. Nullable true. 
FINE: Binding component with path: com.dataobject.Vehicle.movementData 
FINE: Processing com.dataobject.MovementData property annotation 
FINE: Processing annotations of com.dataobject.MovementData.latitude 
FINE: Column(s) overridden for property latitude 
FINE: Binding column LATITUDE. Unique false. Nullable true. 
FINE: binding property latitude with lazy=false 
FINE: building SimpleValue for latitude 
FINE: Building property latitude 
FINEST: Cascading latitude with null 
FINE: Processing annotations of com.dataobject.MovementData.longitude 
FINE: Column(s) overridden for property longitude 
FINE: Binding column LONGITUDE. Unique false. Nullable true. 
FINE: binding property longitude with lazy=false 
FINE: building SimpleValue for longitude 
FINE: Building property longitude 
FINEST: Cascading longitude with null 
FINE: Processing annotations of com.dataobject.MovementData.speed 
FINE: Column(s) overridden for property speed 
FINE: Binding column SPEED. Unique false. Nullable true. 
FINE: binding property speed with lazy=false 
FINE: building SimpleValue for speed 
FINE: Building property speed 
FINEST: Cascading speed with null 
FINE: Processing annotations of com.dataobject.MovementData.timeOfPosition 
FINE: Column(s) overridden for property timeOfPosition 
FINE: Binding column TIME_OF_POSITION. Unique false. Nullable true. 
FINE: binding property timeOfPosition with lazy=false 
FINE: building SimpleValue for timeOfPosition 
FINE: Building property timeOfPosition 
FINEST: Cascading timeOfPosition with null 
FINE: Building property movementData 
FINEST: Cascading movementData with null 
FINE: Processing annotations of com.dataobject.Vehicle.numWheels 
FINE: Binding column NUM_WHEELS. Unique false. Nullable true. 
FINE: binding property numWheels with lazy=false 
FINE: building SimpleValue for numWheels 
FINE: Building property numWheels 
FINEST: Cascading numWheels with null 
INFO: Binding entity from annotated class: com.dataobject.Car 
FINE: Binding column id. Unique false. Nullable false. 
FINE: Subclass joined column(s) created 
FINE: Import with entity name Car 
INFO: Bind entity com.dataobject.Car on table CAR 
FINE: Processing com.dataobject.Car property annotation 
FINE: Processing annotations of com.dataobject.Car.make 
FINE: Binding column MAKE. Unique false. Nullable true. 
FINE: binding property make with lazy=false 
FINE: building SimpleValue for make 
FINE: Building property make 

车辆是父类

/** 
* Entity implementation class for Entity: Vehicle 
* 
*/ 
@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.JOINED) 
@SecondaryTable(name="MOVEMENT_DATA", 
      pkJoinColumns = { 
       @PrimaryKeyJoinColumn(name = "ID") 
      } 
) 
public class Vehicle implements Serializable { 


    private int numWheels; 
    private String color; 
    private int id; 
    private MovementData movementData; 
    private static final long serialVersionUID = 1L; 


    public Vehicle() { 
     super(); 
    } 

    @Embedded 
    @AttributeOverrides({ 
    @AttributeOverride(
     name = "speed", 
     column = @Column(name = "SPEED", 
         table = "MOVEMENT_DATA") 
    ), 
    @AttributeOverride(
     name = "timeOfPosition", 
     column = @Column(name = "TIME_OF_POSITION", 
         table = "MOVEMENT_DATA") 
    ), 
    @AttributeOverride(
      name = "longitude", 
      column = @Column(name = "LONGITUDE", 
          table = "MOVEMENT_DATA") 
     ), 
    @AttributeOverride(
      name = "latitude", 
      column = @Column(name = "LATITUDE", 
          table = "MOVEMENT_DATA") 
     ) 
}) 
    public MovementData getMovementData() { 
     return movementData; 
    } 
    public void setMovementData(MovementData movementData) { 
     this.movementData = movementData; 
    } 

    @Column(name="NUM_WHEELS") 
    public int getNumWheels() { 
     return this.numWheels; 
    } 

    public void setNumWheels(int numWheels) { 
     this.numWheels = numWheels; 
    } 
    @Column(name="COLOR") 
    public String getColor() { 
     return this.color; 
    } 

    public void setColor(String color) { 
     this.color = color; 
    } 
    @Id  
    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

} 

汽车延长车辆

/** 
* Entity implementation class for Entity: Car 
*/ 
@Entity 
@Table(name="CAR") 
public class Car extends Vehicle implements Serializable { 


    private String make; 
    private static final long serialVersionUID = 1L; 

    public Car() { 
     super(); 
    } 
    /** 
    * @return 
    */ 
    @Column(name="MAKE") 
    public String getMake() { 
     return this.make; 
    } 

    /** 
    * @param make 
    */ 
    public void setMake(String make) { 
     this.make = make; 
    } 

} 

MovementData在车载嵌入式

@Embeddable 
public class MovementData implements Serializable { 


    private double speed; 
    private Date timeOfPosition; 
    private double latitude; 
    private double longitude; 
    private static final long serialVersionUID = 1L; 

    public MovementData() { 
     super(); 
    } 



    /** 
    * @return 
    */ 
    @Column(name="SPEED") 
    public double getSpeed() { 
     return this.speed; 
    } 

    /** 
    * @param speed 
    */ 
    public void setSpeed(double speed) { 
     this.speed = speed; 
    } 
    /** 
    * @return 
    */ 
    @Column(name="TIME_OF_POSITION") 
    public Date getTimeOfPosition() { 
     return this.timeOfPosition; 
    } 

    /** 
    * @param timeOfPosition 
    */ 
    public void setTimeOfPosition(Date timeOfPosition) { 
     this.timeOfPosition = timeOfPosition; 
    } 

    /** 
    * @return 
    */ 
    @Column(name="LONGITUDE") 
    public double getLongitude() { 
     return this.longitude; 
    } 

    /** 
    * @param longitude 
    */ 
    public void setLongitude(double longitude) { 
     this.longitude = longitude; 
    } 
    /** 
    * @return 
    */ 
    @Column(name="LATITUDE") 
    public double getLatitude() { 
     return this.latitude; 
    } 

    /** 
    * @param latitude 
    */ 
    public void setLatitude(double latitude) { 
     this.latitude = latitude; 
    } 

} 

持久性单元:

<properties> 
     <!-- The database dialect to use --> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> 
     <!-- drop and create tables at deployment --> 
     <property name="hibernate.hbm2ddl.auto" value="create-drop" /> 
     <!-- Hibernate Query Language (HQL) parser. --> 
     <!-- property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" /--> 
     <!-- property name="hibernate.cache.provider_class" value="org.hibernate.cache.JbossCacheProvider" /--> 
     <property name ="hibernate.show_sql" value="false" /> 
     <property name ="hibernate.format_sql" value="false" /> 
     <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" /> 
    </properties> 

回答

1

在开发过程中往往它便捷的启用此属性:

cfg.setProperty(Environment.HBM2DDL_AUTO, "update"); 

其中CFG是我AnnotationConfiguration。

您的问题将很有可能通过启用此属性来解决。可嵌入类的

+0

我有create-drop set(参见上面的persistence.xml)。我只是用更新来试用它,它仍然不能用于同样的错误。 – systemoutprintln 2009-04-29 20:00:39

+1

对于存在此问题的其他人请注意:答案是自动选中的......这不起作用。 – systemoutprintln 2009-05-07 20:42:09

0

从发布的异常中看起来好像该表尚未在数据库中创建(“找不到表MOVEMENT_DATA”)。如果你没有指示Hibernate/JPA改变你的模式,你必须在运行代码之前手动添加表(我相信它是CREATE-UPDATE来指示hibernate执行alter)。

+0

我已经在我的persistence.xml中拥有了这个 – systemoutprintln 2009-04-28 19:10:11

0

定义不应该参考数据库表:

@Embeddable 
public class MovementData implements Serializable { 


    private double speed; 
    private Date timeOfPosition; 
    private double latitude; 
    private double longitude; 
    private static final long serialVersionUID = 1L; 

    public MovementData() { 
     super(); 
    } 

    @Column(name="SPEED") 
    public double getSpeed() { 
     return this.speed; 
    } 

    ... 

    @Column(name="TIME_OF_POSITION") 
    public Date getTimeOfPosition() { 
     return this.timeOfPosition; 
    } 

    ... 

    @Column(name="LONGITUDE") 
    public double getLongitude() { 
     return this.longitude; 
    } 

    ... 

    @Column(name="LATITUDE") 
    public double getLatitude() { 
     return this.latitude; 
    } 

    ... 
} 

然后车辆实体应确定二次表嵌入式结构包括连接柱:

@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.JOINED) 
@SecondaryTable(name="MOVEMENT_DATA", 
       pkJoinColumns = { 
        @PrimaryKeyJoinColumn(name = "ID") 
       } 
) 
public class Vehicle implements Serializable { 


    private int numWheels; 
    private String color; 
    private int id; 
    private MovementData movementData; 
    private static final long serialVersionUID = 1L; 


    public Vehicle() { 
     super(); 
    } 

    @Embedded 
    @AttributeOverrides({ 
     @AttributeOverride(
      name = "speed", 
      column = @Column(name = "SPEED", 
          table = "MOVEMENT_DATA") 
     ), 
     @AttributeOverride(
      name = "timeOfPosition", 
      column = @Column(name = "TIME_OF_POSITION", 
          table = "MOVEMENT_DATA") 
     ), 

     ... // override the rest of the attributes 

    }) 
    public MovementData getMovementData() { 
     return movementData; 
    } 

    ... 

    @Id  
    public int getId() { 
     return this.id; 
    } 

    ... 
} 

我希望这将为你工作。

+0

感谢您的帮助...尽管如此,仍然得到同样的错误。我不知道该怎么做! – systemoutprintln 2009-05-02 16:47:33

+1

当我遇到这样的问题时,我尝试简化运动场,使其尽可能透明。在这种情况下,我会从Vehicle实体中取出继承设置 - 这样您可以在当时处理一个问题(希望)。在解决了辅助表格中嵌入对象的问题之后,回滚继承并查看它们如何一起工作。 – topchef 2009-05-02 20:34:47

1

我会试着打破这个问题。尝试将移动数据转换为实体,而不是嵌入类。确保它可以独立运行,然后将其更改为可嵌入。

虽然它不是你想要的关系,但你可以尝试使MovementData成为根父级,并让Vehicle从MovementData继承。这样你只会与

@Inheritance(strategy=InheritanceType.JOINED) 

而不是继承加secondaryTable。这将简化关系,但仍包括所有表格。

-1

使用适当的数据库客户端(查询浏览器,MS SQL Managment Studio等)连接到您的数据库来验证这些表是否确实存在。

您可能还想在代码中插入一个断点,以便您可以在引发此错误之前确切地看到数据库看起来像什么。

尝试设置hibernate.hbm2ddl.auto值,以“创造”,如下图,并更改设置,使其打印出来的SQL,所以你可以看到它的尝试:

<props> 
    <!-- some possible values: create, create-drop, update --> 
    <prop key="hibernate.hbm2ddl.auto">update</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    .... 
<props> 

让我知道你在你的分贝中看到了什么。

1

我想这样做太迟了,但是我在寻找别的东西时偶然发现了这个问题。

问题是Embeddable类没有映射到表 - Embeddable对象在数据库中没有标识。

这就是为什么没有生成MovementData表的原因。

我想你已经混淆了嵌入式的含义。正如前面的评论者所述,Vehicle和MovementData应该处于OneToOne关系中,并且嵌入的注释应该被移除。您可能需要Cascade Remove规则以确保如果车辆被移除,MovementData也会被移除。