I have 2 tables event & location in the public schema. 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). I’m trying to use Hibernate to persist the OtherEvent & Other Location.
Every Event has 1+ Locations. 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).
Then hibernate tries to do: UPDATE public.location set event_id=? where location=?
This fails because I don’t have permission on public.location. How can I prevent it from doing this update? Or change it so it does the update on the other.location table.
I tried modifying public.hbm.xml and changing:
<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). This would be because the Location doesn’t have a reference to the Event object.
I cannot change the DB at all. I am using Hibernate 4. What do I do?
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:
<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:
<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:
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
inverseyou’ve tried:should solve it. Only thing in this case is, that we also have to explicitly assign
LocationtoEvent(not only put it into owning collection).Locationshould have a propertyEventThe mapping should be:
So if in the code you will do:
Then it should work with INSERTS only. The inverse means, that child will do all the stuff alone, so it has to know about parent.