2011-08-10 3 views
13

Mam migrować niektóre klasy w pliku hbm.xml Hibernate do adnotacji JPA.Wykluczanie pól z @Embedded properties dla każdego przypadku z Hibernate/JPA

Mamy wbudowaną klasę Address używaną w kilku miejscach. Każde miejsce używa innego podzbioru właściwości w adresie.

(pobierające/ustawiające pominięte dla zwięzłości)

@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; 
} 

Należy zauważyć, że w tym contrived przykład shippingAddress wykorzystuje Address.country, ale billingAddress nie; i żadne z nich nie używa adresu.email.

Problem polega na tym, że stan hibernacji oznacza tagi @Column dla każdej kolumny, w której jej nie podano.

Próbowałem dodanie @Transient wszystkich dziedzinach Address, ale wydaje się, że nie robi @AttributeOverride atutem @Transient.

Czy istnieje sposób obejścia tego problemu?

Odpowiedz

6

Nie sądzę, że adnotacje umożliwiają "ignorowanie" pola z adresu w osadzonych obiektach.

Obejście problemu polega na utworzeniu typu bazowego adresu bez adresu e-mail i adresu rozszerzonego (podklasa adresu) za pomocą pola wiadomości e-mail.

+0

Problem polega na tym, że jest to typowa klasa stosowana w całej naszej organizacji. Szukam sposobu na przeniesienie tej klasy do JPA bez zmiany zachowania lub zmuszenie 30 różnych zespołów do dostosowania swojego kodu. – qualidafial

+0

Należy również zauważyć, że jest to problem związany z przełączeniem JPA na opcję rezygnacji przy użyciu parametru Transient zamiast &at;, a nie z opcjonalnym użyciem kolumny &at;. Pomysł polegał na tym, aby uchwała JPA była mniej inwazyjna, ponieważ nie wymagała ona adnotacji z kolumny wszędzie - jest to tylko efekt uboczny, który nas ugryzł i uniemożliwił przeniesienie tej jednej klasy ze starszej konfiguracji XML do adnotacji JPA. – qualidafial

+0

Jeśli nie możesz zmienić modelu, to nie widzę rozwiązania. Musisz po prostu zignorować właściwości adresu, które nie są używane, a tym samym zostawić je puste w DB. Brudne rozwiązanie, ale najmniej inwazyjne. –

6

Moja rada to utworzenie nowego podmiotu o nazwie PartialAddress/NationalAddress/BillingAddress. To będzie wykorzystywane wyłącznie do mapowania JPA i nie narażone na interfejsie użytkownika:

private PartialAddress billingAddress; 

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

W przeciwnym razie, mam wymyślić nieco brzydki obejście tego problemu, być może będzie pracować dla Ciebie. Zamiast mapowania pola do prawdziwej kolumny, wracam SQL zerowej Constant:

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

Używam Oracle i EclipseLink, działa na Hibernate 3.6, jak również. I testowałem go tylko na obiektach tylko do odczytu. Teoretycznie jednak ustawianie atrybutów insertable i updatable na false powinno wystarczyć.

+2

Jest to bardzo ładne i innowacyjne rozwiązanie. Bezpośrednio odwzorowuję ignorowaną właściwość na wartość null (tj. 'Column = @ Column (name =" null ")' –

+0

Obejście @KenChan'a jest dopuszczalne dla danych, które są trwałe, ale pojawia się problem podczas odczytu z bazy danych. "javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: nie można wyodrębnić ResultSet", a komunikat mówi: "ohejsSqlExceptionHelper - ERROR: column not found tabl0_.null" –

Powiązane problemy