多对一子类外键

时间:2012-11-15 15:29:31

标签: java hibernate hibernate-mapping

我有2个桌子活动&公共架构中的位置。我在“其他”模式中有两个表,它们继承自公共表。有4个类模仿此设置(Event,Location,OtherEvent和& OtherLocation)。我正在尝试使用Hibernate来持久保存OtherEvent&其他位置。

每个活动都有1个以上的地点。事件的位置毫无意义。

如果我创建一个OtherEvent并向其添加一个OtherLocation并尝试保存它,那么hibernate会将OtherEvent插入到other.event& hibernate将OtherLocation插入other.location(包括event_id)。 然后hibernate尝试执行:UPDATE public.location set event_id =?位置=? 这失败是因为我没有public.location的权限。如何阻止它进行此更新?或者更改它以便在other.location表上进行更新。

我尝试修改public.hbm.xml并更改:

<bag name="locations">

<bag name="locations" inverse="true">

这不执行update语句,但是插入到other.location不包含event_id列(在非null上导致ConstraintViolation)。这是因为Location没有对Event对象的引用。

我根本无法更改数据库。我正在使用Hibernate 4.我该怎么办?

以下是所有相关配置: 公共类:

public class Event{
    private String eventId;
    private List<Location> locations;
    //getters & setters
}

public class Location{
    private String locationId;
    private double lat;
    private double lon;
    //getters and setters
}

公共表:

create table public.event{
    event_id varchar PRIMARY KEY,
    event_name varchar,
)

create table public.location(
    location_id varchar PRIMARY KEY,
    event_id varchar NOT NULL, --foreign key to public.event.event_id
    lat double,
    lon double
)

public.hbm.xml:

<hibernate-mapping schema="public">
    <class name="Event" table="event">
        <id name="eventId" column="event_id"/>
        <bag name="locations">
            <key column="event_id" not-null="true"/>
            <one-to-many class="Location">
        </bag>
    </class>
    <class name="Location" table="location">
        <id name="locationId" column="location_id"/>
        <property name="lat" column="lat"/>
        <property name="lon" column="lon"/>
    </class>
</hibernate-mapping>

其他表格:

create table other.event inherits public.event(
    other_information varchar
)

create table other.location inherits public.location(
    other_loc_information varchar
)

其他课程:

public class OtherEvent extends Event{
    private String otherInformation;
    //getter & setter
}

public class OtherLocation extends Location{
    private String otherLocInformation;
    //getter & setter
}

other.hbm.xml:

<hibernate-mapping schema="other">
    <union-subclass name="OtherEvent" extends="Event" table="event">
        <property name="otherInformation" column="other_information"/>
    </union-subclass>
    <union-subclass name="OtherLocation" extends="Location" table="location">
        <property name="otherLocInformation" column="other_loc_information"/>
    </union-subclass>
</hibernate-mapping>

1 个答案:

答案 0 :(得分:1)

我会说解决方案非常接近。你说:

  

我根本无法更改数据库。我正在使用Hibernate 4.我该怎么办?

所以我希望你可以改变代码和映射。如果我是对的,您可以更改代码和映射:您尝试过的inverse设置:

<bag name="locations" inverse="true">

应该解决它。在这种情况下,我们还必须明确地将Location分配给Event(不仅将其置于拥有集合中)。

Location应该有一个属性Event

public class Location{
    private String locationId;
    private Event event;
    private double lat;
    private double lon;
    //getters and setters
}

映射应为:

<class name="Location" table="location">
  <id name="locationId" column="location_id"/>
  <property name="lat" column="lat"/>
  <property name="lon" column="lon"/>
  <many-to-one name="Event" column="event_id" />
</class>

因此,如果在代码中你会这样做:

event.locations.add(location);
location.event = event;

然后它应该只与INSERTS一起使用。相反的意思是,孩子将独自完成所有的事情,因此必须了解父母。