2013-10-02 15 views
6

Mam podmiot o właściwościach DateTime utrzymywały się z hibernacjiJak przekonwertować Joda DateTime w JPA rodzimej zapytania

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
@Column(name = "EFF_DT") 
protected DateTime effDt; 

To wszystko działa dobrze i dobre dla regularne wiosna-data-WZP wygenerowanych zapytaniami.

Próbuję dodać niestandardowy rodzimych zapytaniu

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

Błąd pojawia się podczas próby wywołania jest

java.sql.SQLException: ORA-00932: inconsistent datatypes: expected DATE got BINARY 

Jest to ten sam błąd użyłem, aby uzyskać regularne wiosnę - Wyszukiwarki danych przed dodaniem odwzorowania typu niestandardowego do mojej jednostki

Jak mogę zrobić wiosnę -data-jpa/hibernate używa odwzorowania typu niestandardowego dla parametrów na natywne zapytania?

+0

Znalazłeś odpowiedź na to? –

+0

@ WojciechGórski Nie, nie znalazłem poprawki. W końcu udało mi się ponownie napisać zapytanie w JPA, a następnie włączyłem adnotację hibernacji @ Type, aby obsłużyć konwersję typu '@Query (" select count (ch.circuitId) from nz.co.vodafone.wcim. model.CircuitStateLog ch gdzie ch.effDt między? 1 a? 2 i ch.state =? 3 ")' –

Odpowiedz

0

Wystarczy ustawić właściwość java.util.Date jak ten

następnie przekształcić w getter/setter

public DateTime getEffDt() { 
    return null == effDt ? null : new DateTime(effDt); 
} 

public void setEffDt(final DateTime effDt) { 
    this.effDt = null == effDt ? null : effDt.toDate(); 
} 

Native:

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
Integer countEffDateBetween(Date start, Date end); 
+0

To interesujące rozwiązanie, aby uniknąć używania DateTime, ale w naszym przypadku chcieliśmy zachować pole jako DateTime. –

+0

Dlaczego nie można zmienić wartości 'countEffDateBetween (DateTime start, DateTime end); 'to" countEffDateBetween (Date start, Date end); '? Umożliwiłoby to zachowanie twoich właściwości jako DateTime. –

+1

Używamy DateTime, a nie java.util.Date. Z pewnością, gdybyśmy przestali używać DateTime i używali Date, nie napotkalibyśmy tego problemu. Chcielibyśmy jednak skorzystać z znacznie lepszej wersji interfejsu Joda DateTime API. Moje pytanie brzmi: "jak mogę sprawić, by natywne zapytania działały z DateTime", a nie używanie DateTime nie jest rozwiązaniem tego problemu. –

0

W podobnej sytuacji Przywołałem pisanie niestandardowego typu CompositeUserType, który przechowywał Joda DateTime w dwóch polach, dateti ja pole i pole strefy czasowej.

Po zapisaniu obiektu zapisano wartość czasu w UTC, a strefę czasową jako wartość początkową, podczas pobierania wykonano odwrotność (tj. Przeliczono czas zapisany w bazie danych z powrotem na pierwotną strefę czasową).

Jak już wspomniano powyżej, chociaż zapytanie takie jak "dateTime BETWEEN? 1 AND? 2" ma sens intuicyjny, oczywiście nie ma sensu w kategoriach typów złożonych, ponieważ trzeba pamiętać o strefie czasowej. To był powód, dla którego zapisałem wszystkie wartości w UTC, więc zawsze mogłem porównać dowolne dwie wartości daty/czasu w bazie danych.

Niestety, oznaczało to, że wszystkie parametry zapytania data/czas, które przekazałem, musiały zostać przekonwertowane na UTC.

0

Dokładnie też dostałem to samo wymaganie. I rozwiązałem je, rejestrując typ niestandardowy w konfiguracji hibernacji.

W przypadku natywnych zapytań, opcje TypeDefs nie są wystarczające do hibernacji, aby znaleźć typ użytkownika. Potrzebny jest funkcja rozpoznawania nazw, aby znaleźć jej typy.

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

W takim przypadku tryb hibernacji próbuje odgadnąć typ (org.joda.time.DateTime) z typu resolvers.

Type type = session.getFactory().getTypeResolver().heuristicType(typename); 

Ponieważ nie ma rozpoznawania nazw dla DateTime.Then jest coraz domyślny rodzaj (typ) .i serializable wartość DateTime jest lanego do typu, który jest seryjny i utrzymujące się w DB, gdzie się niepowodzeniem z powodu do dużej wartości binarnej.

Aby rozwiązać ten problem, trzeba zarejestrować typu DateTime do hibernacji konfiguracji jak

configuration.registerTypeOverride(new org.jadira.usertype.dateandtime.joda.PersistentDateTime(), new String[]{"org.joda.time.DateTime"}); 
Powiązane problemy