2012-05-24 5 views
7

Chciałbym użyć adnotacji @Where w stanie hibernacji, aby usunąć obiekty, które zostały oznaczone jako "usunięte" przez właściwość boolean dla tego obiektu. Na przykład następujący powinno zapobiec usunięte adresy z ładowany przez Hibernate:Czy istnieje sposób na zatrzymanie hibernacji przed uszkodzeniem literałów boolowskich w @ adnotacje?

@OneToMany(mappedBy="contact") 
@Where(clause="deleted=FALSE") 
private Set<Address> addresses; 

Jednak kiedy używać klauzuli podobnego deleted=FALSE następnie Hibernate będzie magiel logiczna dosłowne poprzedzając go z nazwą tabeli, która powoduje, że zapytanie do zawieść. Na przykład:

select ... from address address0_ where (address0_.deleted=address0_.FALSE) and address0_.contact_id=? 

Co spodziewałem się coś (address0_.deleted=FALSE) zamiast (address0_.deleted=address0_.FALSE).

Czy istnieje sposób, aby określić klauzulę @Where lub skonfigurować Hibernate, aby poprawnie wyprowadzić wartość boolowską?


PS. Należy pamiętać, że jest to możliwe z niektórych baz danych, aby określić wartość logiczną jako ciąg dosłownym tak:

@Where(clause="deleted='FALSE'") 

To będzie zamieniony na (address0_.deleted='FALSE') który działa dobrze, na przykład, PostgreSQL. Jednak do tego projektu używam HSQLDB, a HSQLDB nie obsługuje boolowskich literałów łańcuchowych. Na HSQL otrzymuję następujący wyjątek podczas korzystania deleted='FALSE':

org.hsqldb.HsqlException: data exception: invalid character value for cast

+0

Czy pamiętasz, aby określić HSQLDB Dialect w konfiguracji hibernacji? – Affe

+0

Tak, używam 'org.hibernate.dialect.HSQLDialect' i sprawdziłem, czy Hibernate faktycznie go używa. – gutch

Odpowiedz

5

odkryłem ten temat raportów o błędach, które zostały nierozwiązane przez ponad sześć lat! Moduł śledzenia problemów Hibernuj ma HHH-1587, HHH-2775 i ANN-647 na problem.

Rozwiązaniem jest utworzenie niestandardowego GWARĘ rejestrujący true, false i unknown jako słów kluczowych (są urzędowe boolowskie literałami w specyfikacji SQL). Powoduje to, że Hibernate rozpoznaje je jako słowa kluczowe, a tym samym przestaje je prefiksować tak, jakby były kolumnami.

Oto moja klasa zwyczaj Dialekt, który rozwiązał problem dla mnie:

public class ImprovedHSQLDialect extends HSQLDialect { 

    public ImprovedHSQLDialect() { 
     super(); 
     registerKeyword("true"); 
     registerKeyword("false"); 
     registerKeyword("unknown"); 
    } 
} 

Gdy to dialekt jest w użyciu, @Where(clause="deleted=FALSE") działa poprawnie.

1

Gdy kolumna jest tworzona jako BOOLEAN w definicji tabeli, najnowszy HSQLDB obsługuje WHERE active = TRUE, WHERE active = 'TRUE', a także WHERE active.

Hibernacja może tworzyć kolumnę BIT, w takim przypadku zadziała WHERE active = TRUE, WHERE active = B'1' lub WHERE active = 1.

Dla tych funkcji należy używać wersji 2.2.8 lub nowszej.

+0

Jesteś tego pewien? Błąd opisany w moim pytaniu wystąpił na najnowszym HSQLDB (wersja 2.2.8).Obecna dokumentacja nie wspomina o żadnej obsłudze konwersji łańcuch-boolean w http://hsqldb.org/doc/guide/sqlgeneral-chapt.html, więc nie jestem przekonany, że jest to funkcja HSQLDB. – gutch

+0

Dokumenty nie mogą obejmować wszystkich możliwych konwersji. Jeśli tabela ma kolumnę BOOLEAN, wszystkie powyższe działają. Hibernacja musi tworzyć kolumnę BIT, w którym to przypadku WHERE active = TRUE, WHERE active = B'1 'lub WHERE active = 1 będzie działać. – fredt

+0

W takim przypadku możliwe jest, że podanie odpowiedniego 'columnDefinition' w adnotacji' @ Column' może sprawić, że będzie działało. Ale jeśli chodzi o mnie, to jest źle, gdy Hibernate traktuje zarezerwowane słowo jak 'FALSE' jako nazwę kolumny, więc myślę, że lepszym rozwiązaniem jest użycie metody' registerKeyword', jak opisuję w mojej odpowiedzi - jest to proste i natychmiastowe naprawia go we wszystkich obiektach hibernacji. – gutch

Powiązane problemy