Подтвердить что ты не робот

Исключение полей из свойств @Embedded в каждом конкретном случае с Hibernate/JPA

Я переношу некоторые классы в файле hibm.xml Hibernate на аннотации JPA.

У нас есть вложенный класс Address, который используется в нескольких местах. Каждое место использует другое подмножество свойств в адресе.

(геттеры/сеттеры опущены для краткости)

@Embeddable
public class Address {
  String email;
  String address;
  String city; 
  String state;
  String zip;
  String country;
}

@Entity
@Table(name="customer")
public class Customer {
  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="address", [email protected](name="ship_addr"),
    @AttributeOverride(name="city", [email protected](name="ship_city"),
    @AttributeOverride(name="state", [email protected](name="ship_state"),
    @AttributeOverride(name="zip", [email protected](name="ship_zip"),
    @AttributeOverride(name="country", [email protected](name="ship_country")
  })
  Address shippingAddress;

  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="address", [email protected](name="bill_addr"),
    @AttributeOverride(name="city", [email protected](name="bill_city"),
    @AttributeOverride(name="state", [email protected](name="bill_state"),
    @AttributeOverride(name="zip", [email protected](name="bill_zip")
  })
  Address billingAddress;
}

Обратите внимание, что в этом надуманном примере shippingAddress использует Address.country, но billingAddress не работает; и ни один из них не использует Address.email.

Проблема в том, что Hibernate выводит теги @Column для любого столбца, где я явно не предоставил его.

Я попробовал добавить @Transient ко всем полям Address, но кажется, что @AttributeOverride не trump @Transient.

Есть ли какое-либо обходное решение для этого?

4b9b3361

Ответ 1

Я не думаю, что с аннотациями можно "игнорировать" поле из адреса во встроенных объектах.

Обходным путем является создание базового типа Address без электронной почты и ExtendedAddress (подкласс адреса) с полем электронной почты.

Ответ 2

Моим советом было бы создать новый объект под названием PartialAddress/NationalAddress/BillingAddress. Это будет использоваться только для отображения JPA и не будет отображаться на интерфейсе Customer:

private PartialAddress billingAddress;

public Address getBillingAddress() {
    return billingAddress.toAddress();
}

В противном случае, я придумал несколько уродливое обходное решение этой проблемы, возможно, это сработает и для вас. Вместо того, чтобы сопоставлять поле с реальным столбцом, я возвращаю константу null:

@Embedded
@AttributeOverrides({
    @AttributeOverride(name="address", [email protected](name="bill_addr"),
    @AttributeOverride(name="city", [email protected](name="bill_city"),
    @AttributeOverride(name="state", [email protected](name="bill_state"),
    @AttributeOverride(name="zip", [email protected](name="bill_zip"),
    @AttributeOverride(name="country", [email protected](name="bill_id + null"),
})
Address billingAddress;

Я использую Oracle и EclipseLink, также работает на Hibernate 3.6. И я тестировал его только на объектах только для чтения. Хотя теоретически установка атрибутов insertable и updatable на false должна быть достаточной.