У меня есть два объекта PointOfInterest (называемый здесь POI) и его адрес. Я хочу определить одно к одному двунаправленное сопоставление с общим первичным ключом между ними, с POI как объект владельца. Я использую postgreSQL DB, таблица POI имеет POIId как PK, сгенерированный генератором последовательности, определенным в БД. Таблица адресов имеет столбец POIId, который является таблицей адресов PK, а также столбец POII таблицы FK для POI, а также другие столбцы.Hibernate @OneToOne с общим основным ключом (двунаправленный). Зависимый объект не сохраняется в БД.
**PointOfInterest.java**
@Entity
@Table(name = "\"POI\"")
public class PointOfInterest implements Serializable {
private static final long serialVersionUID = -5406785879200149642L;
@Id
@Column(name="\"POIId\"", nullable=false)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="poi_seq_poiid_generator")
@SequenceGenerator(name = "poi_seq_poiid_generator", sequenceName = "poi_seq_poiid", allocationSize=1)
private Long poiId;
@OneToOne(mappedBy = "poi",cascade = CascadeType.PERSIST)
private Address address;
//Other fields
-----------------------------------------------------------------
**Address.java**
@Entity
@Table(name="\"Address\"")
public class Address implements Serializable{
private static final long serialVersionUID = -7146133528411371107L;
@Id
@GeneratedValue(generator="sharedPrimaryKeyGenerator")
@GenericGenerator(name="sharedPrimaryKeyGenerator",strategy="foreign",parameters = @Parameter(name="property", value="poi"))
@Column(name="\"POIId\"")
private Long poiId;
@OneToOne
@PrimaryKeyJoinColumn
private PointOfInterest poi;
Перед сохранением объекта POI с использованием session.saveOrUpdate (poi). Я создаю экземпляр и задаю все другие свойства объекта POI. Затем получите объект Address из отдельного метода в моей логике и сделайте что-нибудь вроде.
PointOfInterest poi = methodCallToGetPOI();
Address address = methodCallToGetAddress();
poi.setAddress(address);
address.setPOI(poi);
//Send POI object to DB layer to an appropriate method which does:
session.saveOrUpdate(poi);
session.flush();
Когда я вижу сгенерирован запрос, я вижу что-то вроде этого:
Hibernate:
select
nextval ('poi_seq_poiid')
Hibernate:
insert
into
"POI"
("CreatedBy", "CreatedTime", "LocationGeographic", "ModifiedBy", "ModifiedTime", "Name", "POICode", "Radius", "POIType", "POIId")
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Таким образом, очевидно, спящий режим не делает оператор вставки в таблицу адресов. Я искал всюду в Интернете и сравнивал мои сопоставления, они кажутся правильными. Однако ни одна строка не вставлена в таблицу адресов. Когда я отлаживаю поток, я обнаружил, что объект адреса создается и заполняется. Пожалуйста, помогите мне разобраться, почему это так. Единственная причина, по которой я могу думать об этом, что я использую генератор последовательности, а во всех примерах и фрагментах кода в Интернете все используют стратегию генерации генерации гиберната, значит, из-за этого? Я не могу использовать ключ автогенератора, я должен использовать только свою последовательность БД. Если эти аннотации не будут работать, любезно предложите альтернативу.
Я использую Spring и Hibernate с пружинным Framework версии 4.0.5.RELEASE и сессионными фабриками, полученных из org.springframework.orm.hibernate4.LocalSessionFactoryBean и менеджером транзакций, полученная из org.springframework.orm.hibernate4.HibernateTransactionManager.
Привет, Спасибо за ваш ответ, но проблема не решена. Только объект PointOfItnerest заполняется. Не могли бы вы также объяснить, почему генератор adhoc не требуется? – nbnb
Вы правы, я тестировал его на Hibernate 5.2.2, и он больше не работает. см. обновление для альтернативного сопоставления, которое заботится о ссылке ID. Обратите внимание, что я тестировал только генерацию DDL, не знаю, будет ли идентификатор адреса автоматически заполняться во время выполнения (но он должен). –
Спасибо за редактирование :) Я на самом деле заработал. Просто изменил cascadeType на cascadeType.ALL и вдруг строки адреса вставляются. – nbnb