Hibernate映射与一对多的多态关系

Hibernate映射与一对多的多态关系

本文介绍了Hibernate映射与一对多的多态关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类图,我想将其映射到数据库(请注意,Person具有类Vehicle的对象的列表)。

I have the following class diagram and I want to map it to a database (note that Person has a list with objects of class Vehicle).

另外我的数据库看起来像:


表示Vehicle类子类的数据库中的所有表都具有超类Vehicle的所有字段。此外,所有的关系都显示出从人到车,汽车和摩托车的一对多关系。

Also my database looks like:
All tables in the database that represent a subclass of the Vehicle class have all the fields of the superclass Vehicle. Also, all the relations show a one-to-many relationship from Person to Vehicle, Car and Motorcycle.

我的 hibernate映射文件是以下:
Person.hbm.xml

<hibernate-mapping package="....">
    <class name="Person" table="Persons">
        <id name="key" column="Person_ID">
            <generator class="native"/>
        </id>
        <list name="ownedVehicles" inverse="false" cascade="all">
            <key column="Person_ID" not-null="true" />
            <list-index column="idx"/>
            <one-to-many class="Vehicle"/>
        </list>
    </class>
</hibernate-mapping>

Vehicle.hbm.xml

<hibernate-mapping package="...">
    <class name="Vehicle" table="Vehicles"  polymorphism="implicit">
        <id name="id" type="int" column="Vehicle_ID">
            <generator class="increment"/>
        </id>
        <property name="numOfSeats"/>
        <union-subclass name="Car" table="Cars"></union-subclass>
        <union-subclass name="Motorcycle" table="Motorcycles"></union-subclass>
    </class>
</hibernate-mapping>

问题(我得到的错误)如下:

The problem (error I get) is the following:

Hibernate: insert into Persons (Person_ID) values (default)
2013-06-26 15:41:52 WARN  JdbcCoordinatorImpl:424 - HHH000386: ResultSet had no statement associated with it, but was not yet registered
Hibernate: update Car set numOfSeats=? where Vehicle_ID=?
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

我运行时收到此错误:

Car car = new Car();
car.setNumOfSeats(5);
Person person = new Person();
person.getOwnedVehicles().add(car);
ManagePerson managePerson = new ManagePerson();
Integer personID = managePerson.store(person);

ManagePerson的 store()功能实际上创建了一个会话和一个事务然后使用Hibernate提供的 save()方法将对象保存到数据库中。

The store() function of ManagePerson actually creates a session and a transaction and then uses the save() method provided by Hibernate to persist the objects into the database.

据了解,Hibernate通常会做插入人员,然后插入汽车,最后更新汽车(更新完成,以保存汽车表上的外键,将引用拥有汽车的人)。然而,在这里并不是这样,插入汽车似乎被跳过了。我知道Hibernate如何在这里尝试使用 person.getOwnedVehicles()。add(vehicle); 而不是 person.getOwnedVehicles()。add(car) ; 上面给出的代码。

你可能会明白,我试图看看Hibernate是否真的明白了在哪个子类表中记录应该去,取决于类包含在Person类的ownedVehicle列表中的对象。例如,如果拥有的车辆具有Car类和摩托车类之一的对象,那么这些对象应分别转到汽车和摩托车表。

As far as I understand Hibernate usually will do insert into Persons, then insert into Cars and finally update Cars (the update is done to save the foreign keys on Cars table that will reference the Person that owns the cars). However, here this is not the case and the insert into Cars seems to be getting skipped. I understood how Hibernate works here by trying person.getOwnedVehicles().add(vehicle); instead of person.getOwnedVehicles().add(car); on the code given above.
As you might understand, I am trying to see if Hibernate actually understands in which "subclass" table a record should go, depending on the class of the object contained in the ownedVehicle list of the Person class. For example, if the ownedVehicles has an object of class Car and one of class Motorcycle, then each of these should go to Cars and Motorcycle tables respectively.

注意:我正在使用Hibernate 4.2.2和HSQLDB 2.2.9。

我希望有任何帮助。

谢谢。

I would appreciate any help with this.
Thanks.

推荐答案

我认为这只是一个不正确使用Hibernate的隐式多态性的问题。
您的案例的隐式多态性只能通过将列表更改为
inverse =true才能生效。当然,如果你的车辆类也'知道'与人类的关系(例如添加一个'所有者'属性和相应的映射),这可以完成。

I think it is just a matter of incorrect use of the implicit polymorphism of Hibernate.Implicit polymorphism for your case can only work by changing your list to haveinverse="true". This can be done of course if your Vehicle class also 'knows' about the relationship with the Person class (e.g. by adding an 'Owner' property and the corresponding mapping).

这个表和每个具体类(union-subclass)表和一对多关联的情况。

(Have a look at this table and the case of "table per concrete-class (union-subclass)" and one-to-many associations.

如果启用日志记录并提高日志级别到DEBUG你会看到目前的Hibernate试图用Person_ID而不是像你的意思来更新Vehicle表,这是因为inverse =true以及Table-per的组合的限制-concrete-class映射策略和隐式多态(查看文档)。

If you enable logging and raise the log level to DEBUG you would see that currently Hibernate tries to update the Vehicles table with the Person_ID instead of the Car table like you meant it to. This is because of the inverse="true" and the limitations of the combination of the Table-per-concrete-class mapping strategy and implicit polymorphism (have a look at the documentation).

所以,通过让Vehicle类知道它的所有者,并使用inverse =true 你应该能够在你想要的d中取得成功o。或者尝试其他继承映射策略(再次查看文档)。

So, by having the Vehicle class know about its Owner and using inverse="true" you should be able to succeed in what you are trying to do. Either this or try one of the other inheritance mapping strategies (again have a look at the documentation).

这篇关于Hibernate映射与一对多的多态关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 08:16