Чтобы решить эту проблему, вам нужно сделать две вещи.
Добавление @MapsId
к дочерней таблице
Как я объяснил в этой статье , @MapsId
- это единственный способ сопоставить истинное отношение «один к одному» :
@Entity
@Table(name = "FNACHRICHTAKTSTATUS")
public class FNachrichtAktStatus implements Serializable {
private static final long serialVersionUID = 1L;
@OneToOne
@MapsId
@JoinColumn(name = "FN_NR", referencedColumnName = "FN_NR")
private FsakNachricht fsakNachricht;
@Column(name = "FN_AKTSTATUS", length = 30)
private String fnAktStatus;
// Getter / Setter
}
Без @MapsId
, вы бы использовали отношение таблицы «один ко многим», где столбец FK имеет уникальное ограничение. Это нежелательно, так как вам придется тратить один лишний столбец.
Как избежать связи с родительской стороной
Прежде всего, на родительской стороне необходимо использовать mappedBy
вот так:
@Entity
@Table(name = "FSAK_NACHRICHT")
public class FsakNachricht implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FSAK_NACHRICHT_FNNR_GENERATOR")
@SequenceGenerator(name = "FSAK_NACHRICHT_FNNR_GENERATOR", sequenceName = "SEQ_FSAK_NACHRICHT", allocationSize = 1)
@Column(name = "FN_NR", unique = true, nullable = false, updatable = false)
private long fnNr;
// one-to-one association to FNachrichtAktStatus
@OneToOne(mappedBy = "fsakNachricht")
private FNachrichtAktStatus fnachrichtAktStatus;
// Other attributes, Getter / Setter
}
Однако, как объяснено в этой статье , именно из-за этой связи @OneToOne
со стороны родителя Hibernate генерирует дополнительный запрос, так как ему нужно с нетерпением получить ассоциацию, чтобы узнать, назначить ли атрибут для null
или для прокси.
Итак, лучше удалить эту родительскую связь:
@Entity
@Table(name = "FSAK_NACHRICHT")
public class FsakNachricht implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FSAK_NACHRICHT_FNNR_GENERATOR")
@SequenceGenerator(name = "FSAK_NACHRICHT_FNNR_GENERATOR", sequenceName = "SEQ_FSAK_NACHRICHT", allocationSize = 1)
@Column(name = "FN_NR", unique = true, nullable = false, updatable = false)
private long fnNr;
// Other attributes, Getter / Setter
}
Вы всегда можете выбрать дочернюю сущность через идентификатор родительской сущности:
FNachrichtAktStatus fnachrichtAktStatus = entityManager.find(
FNachrichtAktStatus.class,
fsakNachricht.getFnNr()
);
Таким образом, вы будете извлекать эту связь только при необходимости, поэтому избегая проблем с N + 1 запросами. .