W skrócie moje klasy wyglądały tak:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorValue("PLAYER_SHORT_INFO")
public class PlayerShortInfo implements IsSerializable {
@Id @GeneratedValue
@Column(name = "ID", unique = true, nullable = false)
private long id;
[...]
}
@Entity
@DiscriminatorValue("PLAYER_INFO")
@PrimaryKeyJoinColumn(name="ID")
public class PlayerInfo extends PlayerShortInfo implements IsSerializable {
@ManyToOne(optional = false, cascade = {CascadeType.REFRESH, CascadeType.PERSIST}, fetch = FetchType.EAGER)
PlayerType type;
[...]
}
Nigdy nie tworzyłem obiektów klasy PlayerShortInfo.Dziedziczneie było zrobione głownie dla ograniczenie ilości danych przesylanych klientowi, gdy potrzebuje tylko danych skróconych (ale na przykład nie dla jednego obiektu, a dla 100). Takie rozwiązanie wydało mi sie proste i wydajne. Niestety, dziś okazało sie inaczej.
Klasa PlayerInfo, jest klasa która nigdy nie jest przekazywana do warstwy WEB. Jest wykorzystywana tylko w logice biznesowej, a wiec nawet nie było potrzeby, aby implementowała IsSerializable (wymagane przez GWT). W czasie testów, wyszło jednak, ze GWT nie może przetransportować listy zawierającej PlayerShortInfo ponieważ PlayerType (!!!) nie implementuje IsSerializable. Po sprawdzeniu, okazało sie, ze zeczywiscie nie implementuje, tylko ze PlayerType nigdy nie miał być przesyłany do warstwy WEB.
Po dłuższych poszukiwaniach, okazało sie ze SELECT: (List
Wnioski:
InheritanceType.SINGLE_TABLE jest nieco mylące. Obiektem ładowanym z bazy jest zawsze obiekt który został zapisany, nawet jeżeli w Select jest jasno podane ze chcemy załadować obiekt wyższego rzędu. Co sie dzieje, jest wykonywane załadowanie obiektu który został zapisany a następnie rzutowanie go na element docelowy. Sprawa jest bardziej skomplikowana, bo jeżeli dziecko jest obiektem ciężkim, to pomimo ze chcemy załadować lekkiego rodzica, załadowany zostanie ciężki obiekt dziecka, razem ze wszystkimi atrybutami które ono posiada (na przykład listami innych obiektów).
Rozwiązanie:
Moim zdaniem nie ma dobrego rozwiązania. Trzeba być świadomym problemu i stosować takie rozwiązania w swojej aplikacji, aby nie było potrzeby stosowania tego rodzaju dziedziczenia.
Brak komentarzy:
Prześlij komentarz