2013-01-10 14 views
7

Używam hibernacji i adnotacji dla ORM. Mam interfejsy dla wszystkich komponentów bean i używam targetEntity dla relacji: hibernate nie może wyprowadzić typu, ponieważ getter zwraca interfejs zamiast komponentu bean.Nadpisanie @ManyToOne targetEntity dla @Embedded z interfejsami

Otrzymuję wyjątek MappingException (nie można określić typu) dla zagnieżdżonych komponentów bean.

@Entity(name="FieldBean") 
public class FieldBean implements Field { 
    ... 
} 

@Embeddable 
public class FacetBean implements Facet { 
    ...  

    @ManyToOne(targetEntity = FieldBean.class) 
    @JoinColumn(name = "field_id") 
    public Field getField() { 
     return field; 
    } 

} 

@Entity(name = "Chart") 
public class ChartBean implements Chart { 

    @Embedded 
    @AssociationOverride(
     name = "field", 
     joinColumns = @JoinColumn(name = "category_facet_field_id") 
    ) 
    public Facet getCategoryFacet() { 
     return categoryFacet; 
    } 

} 

uzyskać MappingException: nie można określić typ dla: Pole, w tabeli: wykres, na kolumnach: [org.hibernate.mapping.Column (pole)]

Korzystanie fasola zamiast interfejsy dla deklaracje właściwości i getter/setter rozwiązują problem, ale chciałbym trzymać się za pomocą interfejsów. Używanie komponentów bean do samych deklaracji właściwości nie rozwiązuje problemu.

Czy ktoś może wskazać mi właściwy kierunek?

Odpowiedz

0

Moja przeszłość z użyciem jpy mówiła, że ​​nie powinienem używać dziedziczenia. Brak mapowanych superklatek, brak interfejsów itp. ... po prostu podmioty z członkami. Pracowałem z hibernacją, a także eclipselink i oba mają naprawdę, naprawdę problemy z dziedziczeniem. Trudno jest napisać warstwę trwałości z jpa, która obsługuje więcej niż jednego dostawcę, ponieważ jest tak wiele błędów wszystkich tych dostawców. utrzymuj to tak proste, jak to tylko możliwe. nie używaj żadnych "specjalnych" funkcji. Zapewniam, że próbując zmienić dostawcę lub po prostu uruchamiając oprogramowanie na różnych serwerach aplikacji, takich jak jboss (hibernate) lub glassfish/weblogic (eclipse/top link), możesz być zadowolony, gdy masz najbardziej prostą warstwę uporczywości, która używa tak mało funkcje, jak to możliwe. Nie wiem, czy to błąd, ale zakładam, że tak.

+0

Używam interfejsy i dziedziczenie. Przyznano, że wprowadziło to pewną złożoność na poziomie ORM. Z drugiej strony zapewnia mi poziom abstrakcji, którego szukam. – user1966634

+0

** Interfejsy ** są używane w celu zapewnienia abstrakcji technologii ORM. Za pomocą podejścia MDA generuję kod warstwy trwałości z modelu obiektowego, w tym interfejsy, komponenty bean i klasy usług. Alternatywną technologię ORM można stosować w sposób przejrzysty, utrzymując stabilność interfejsów, ale generując alternatywne ziarna i klasy usług. – user1966634

+0

** Dziedziczenie ** jest potrzebne z perspektywy modelowania danych do obsługi zarówno ogólnych, jak i szczegółowych widoków danych, w szczególności, ale nie wyłącznie, na relacyjnym poziomie bazy danych. Pomimo niektórych wad funkcja ta jest użyteczna i upraszcza kod na wyższych poziomach w stosie aplikacji. – user1966634

1

Od pewnego czasu używam do tego praktycznego rozwiązania, ale zawiera ono niewielki przypadek blokady dostawcy. Nie znalazłem sposobu, aby to zrobić tylko z adnotacjami JPA, ale istnieje adnotacja specyficzna dla Hibernate @Target, która rozwiązuje problem. Zrobiłem coś takiego jak ty, z oczekiwanymi rezultatami. Jednak nie użyłem innych adnotacji, więc nie mogę zagwarantować, że wszystko będzie działać zgodnie z oczekiwaniami.

Nic dziwnego dzieje się w zanurzalna klasach:

public interface PointsInt extends Serializable { 
    int offensivePoints(); 

    int defensivePoints(); 

} 

@Embeddable 
public class Points implements PointsInt { 
    private int def; 
    private int off; 
    public int offensivePoints() { return off; } 

    public int defensivePoints() { return def; } 

} 

Ale w klasie zużywającego, używamy Hibernate @Target:

import javax.persistence.*; 
import org.hibernate.annotations.Target; 

@Entity 
public class Series extends LongIdEntity implements Serializable { 

    @Embedded 
    @Target(Points.class) 
    private PointsInt points; 
    // I prefer to declare my annotations on fields rather than methods 
} 

Wynik:

mysql> describe series; 
+-----------------+-------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+-----------------+-------------+------+-----+---------+----------------+ 
| id    | bigint(20) | NO | PRI | NULL | auto_increment | 
| def    | int(11)  | YES |  | NULL |    | 
| off    | int(11)  | YES |  | NULL |    | 
+-----------------+-------------+------+-----+---------+----------------+ 
3 rows in set (0.12 sec)