简体   繁体   English

多对一子类外键

[英]Many-to-One Subclass Foreign Key

I have 2 tables event & location in the public schema. 我在公共架构中有2个表事件和位置。 I have two tables in the 'other' schema which inherit from the public tables. 我在“其他”模式中有两个表是从公共表继承的。 There are 4 classes that mimic this setup (Event, Location, OtherEvent, & OtherLocation). 有4个模拟此设置的类(事件,位置,OtherEvent和OtherLocation)。 I'm trying to use Hibernate to persist the OtherEvent & Other Location. 我正在尝试使用Hibernate来保存OtherEvent&Other Location。

Every Event has 1+ Locations. 每个活动都有1+个地点。 A Location is meaningless with an Event. 地点对于事件毫无意义。

If I create an OtherEvent and add an OtherLocation to it and try to save it, hibernate inserts the OtherEvent into other.event & hibernate inserts the OtherLocation into other.location (including the event_id). 如果我创建一个OtherEvent并向其添加OtherLocation并尝试保存,则hibernate会将OtherEvent插入other.event中,hibernate会将OtherLocation插入other.location中(包括event_id)。 Then hibernate tries to do: UPDATE public.location set event_id=? 然后休眠尝试做:更新public.location设置event_id =? where location=? 位置=? This fails because I don't have permission on public.location. 失败是因为我没有对public.location的许可。 How can I prevent it from doing this update? 如何防止它执行此更新? Or change it so it does the update on the other.location table. 或对其进行更改,以便对other.location表进行更新。

I tried modifying public.hbm.xml and changing: 我尝试修改public.hbm.xml并更改:

<bag name="locations">

to

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

This doesn't do the update statement, but the insertion into other.location doesn't include the event_id column (causing a ConstraintViolation on the not null). 这不执行update语句,但是插入other.location中不包括event_id列(导致ConstraintViolation不为null)。 This would be because the Location doesn't have a reference to the Event object. 这是因为Location没有对Event对象的引用。

I cannot change the DB at all. 我根本无法更改数据库。 I am using Hibernate 4. What do I do? 我正在使用Hibernate4。我该怎么办?

Here is all of the relevant configs: Public Classes: 这是所有相关的配置:公共类:

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
}

Public Tables: 公开表:

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: 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>

Other Tables: 其他表:

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

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

Other Classes: 其他课程:

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

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

other.hbm.xml: 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>

I would say that the solution is very close. 我会说解决方案非常接近。 You said: 你说:

I cannot change the DB at all. 我根本无法更改数据库。 I am using Hibernate 4. What do I do? 我正在使用Hibernate4。我该怎么办?

So I expect that you can change the code and mapping. 因此,我希望您可以更改代码和映射。 If I am right and you can change the code and mapping: the setting inverse you've tried: 如果我是对的,那么您可以更改代码和映射:您尝试过的设置inverse

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

should solve it. 应该解决它。 Only thing in this case is, that we also have to explicitly assign Location to Event (not only put it into owning collection). 在这种情况下,唯一的事情是,我们还必须显式将Location分配给Event (不仅将其放入拥有的集合中)。

Location should have a property Event Location应该有一个属性Event

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

The mapping should be: 映射应为:

<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>

So if in the code you will do: 因此,如果在代码中,您将执行以下操作:

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

Then it should work with INSERTS only. 然后,它仅应与INSERTS一起使用。 The inverse means, that child will do all the stuff alone, so it has to know about parent. 相反的意思是,那个孩子将独自做所有的事情,因此它必须了解父母。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM