2012-08-07 9 views
17

mam Hibernate udało Java podmiot o nazwie X i funkcję natywnego SQL (myFunc), który ja nazywam z kwerendy hibernacji SQL wzdłuż tych linii:Jak najlepiej odwzorować wyniki z zapytania SQL do obiektu Java nie będącego jednostką przy użyciu Hibernuj?

SQLQuery q = hibernateSession.createSQLQuery(
        "SELECT *, myfunc(:param) as result from X_table_name" 
      ); 

Co chcę zrobić, to odwzorować wszystko wróciło z to zapytanie do klasy (niekoniecznie zarządzanej przez Hibernate) o nazwie Y. Y powinno zawierać wszystkie właściwości/pola od X plus result zwrócone przez myfunc, np. Y może rozszerzyć klasę X i dodać pole "wyniku".

Co próbowałem:

  1. Próbowałem za pomocą q.addEntity(Y.class) ale to się nie powiedzie się: org.hibernate.MappingException: Unknown entity com.mycompany.Y
  2. q.setResultTransformer(Transformers.aliasToBean(Y.class)); ale to się nie powiedzie się: org.hibernate.PropertyNotFoundException: Could not find setter for some_property. X ma pole o nazwie someProperty z odpowiednim programem pobierającym i ustawiającym, ale w tym przypadku nie wygląda na to, że Hibernate odwzorowuje nazwę kolumny (some_property) na poprawną nazwę pola.
  3. q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); zwraca mapę, ale wartości nie zawsze są typu oczekiwanego przez odpowiednie pole w X. Na przykład pola w X typu enum i Date nie mogą być mapowane bezpośrednio z mapy zwróconej przez zapytanie SQL (gdzie są Smyczki).

Jaki jest właściwy sposób radzenia sobie z tą sytuacją?

Odpowiedz

15

Zobacz chapter of the documentation about SQL queries.

Możesz użyć metody addScalar(), aby określić, jakiego typu powinien używać Hibernat dla danej kolumny.

i można użyć aliasów do odwzorowywania wyników z właściwościami Fasola:

select t.some_property as someProperty, ..., myfunc(:param) as result from X_table_name t 

Albo (a mimo to wymaga kilku linii kodu, to moja preferowanym rozwiązaniem), można po prostu zrobić mapowanie samodzielnie :

List<Object[]> rows = query.list(); 
for (Object[] row : rows) { 
    Foo foo = new Foo((Long) row[0], (String) row[1], ...); 
} 

Pozwala to uniknąć refleksji i pozwala kontrolować wszystko.

+2

Eek, obsada do "Długiego". Skąd wiesz, że 'wiersz [0]' będzie miał postać 'Long'? Czy istnieje sposób wymuszania konwersji typów danych za pomocą interfejsów API Hibernate? –

+0

@LukasEder: Skorzystaj z linku do dokumentacji, to tam jest wyjaśnione. Jednak korzystanie z zapytań SQL z Hibernate powinno być wyjątkowo wyjątkowe. W większości przypadków używasz kwerend HQL/kryteriów, a typ wyprowadza się z typu pola w twojej encji. –

+0

Dzięki za informacje. Powinienem był całkowicie przeczytać twoją odpowiedź ...Mimo to, wciąż jest trochę trudu, aby informacje o typie musiały zostać powtórzone. –

0

Przede wszystkim trzeba zadeklarować podmiot w konfiguracji hibernacji pliku XML tak: ..... class = „Ścieżka do swojej jednostki”

lub możesz zrobić to samo przed programowo tworzysz zapytanie.

6

Łatwo. Rzuć rzędy do: Map<String, Object>:

+0

Przyjemny pomysł, ale działa tylko wtedy, gdy kolumny bazy danych mają taką samą nazwę jak pola encji. –

+0

Świetne rozwiązanie .... Dzięki – sarwar026

Powiązane problemy