Freitag, Juni 5, 2020

JPA: Wie führen Sie eine WIE mit eine Spalte „NUMMER“ in ein statisches JPA-Metamodell?

Ich habe eine statische Metamodell mit einer ZAHL (tatsächlich, BigDecimal, fragt bitte nicht warum) – Spalte. Jetzt würde ich gerne eine LIKE-Abfrage, die Spalte „Nummer“:

CriteriaBuilder cb;
cb.like(entity.get(Entity_.numbercol), "123%");

wo entity.get(Entity_.numbercol) gibt eine Path<BigDecimal>. Natürlich, ich bekomme einen kompilieren Fehler: ...like(Expression<String>, ...) ... not applicable for the arguments (Path<BigDecimal>, ...)

Casting der Spalte mit .as(String.class) scheitert aufgrund einiger Fehler in der PPV, aber ich habe nicht die bug-Nummer in die Hände, gerade jetzt. Es ist nicht fest in die neueste version von JPA/Hibernate, obwohl. Sowieso, es kommt zu einer exception zur Laufzeit, über einige ungültige SQL-Anweisung generiert wird.

Nun brauche ich nur noch einen Weg, um die Kriterien API-äquivalent zu der SQL

... WHERE numbercol LIKE '123%';

Suche nach dem Thema schon brachte die folgenden Antworten, die nicht helfen, weil ich eine statische Metamodell:
NHibernate – einfachste Weg, um eine LIKE-Suche gegen eine integer-Spalte mit den Kriterien-API? und JPA/Criteria API – Wie & gleichen problem

Irgendwelche Ideen?

Vielen Dank im Voraus
Dominik

  • Als workaround, und weil sichergestellt ist, dass der Platzhalter ist immer das Letzte Zeichen der Zeichenkette/Zahl, die ich erstellen Sie eine Reihe von zwischen Ausdrücke, z.B. für 123% ich habe =123 OR between (1230,1239) OR between(12300, 12399) OR between(123000, 123999) und so weiter. Nicht der beste Weg, aber zumindest funktioniert es.

2 Kommentare

  1. 0

    Nein, es schlägt nicht fehl, weil der Fehler, es funktioniert wie angegeben (zum Beispiel in Javadoc):

    Führen eine Typumwandlung auf den Ausdruck, die einen neuen Ausdruck
    Objekt. Diese Methode verursacht keine Typ-Konvertierung: die runtime-Typ
    wird nicht geändert. Warnung: kann Ergebnis in eine runtime-Fehler.

    Methode, die Sie verwenden führt gegossen und Sie brauchen Bekehrung. Im Allgemeinen gibt es keine Unterstützung zur Konvertierung von BigDecimal String in JPA.

    • Gut, ich weiß, aber es ist auch irgendwo ein Fehler, die wir Schritt über. Trotzdem, vielen Dank für den Hinweis, dass sich hier in diesem Zusammenhang, dass sollte helfen.
  2. 12

    Für die Menschen, die noch auf der Suche nach einer Lösung.

    Wissen, dass HQLstr Funktion macht den job (zumindest für Hibernate v. 3.6.9.Final) kann man die Verwirklichung seiner eigenen FunctionExpression wie:

    //plagiarized from org.hibernate.ejb.criteria.expression.function.CastFunction
    public class StrFunction<Y extends Number> extends BasicFunctionExpression<String> implements FunctionExpression<String>, Serializable {
        public static final String FCT_NAME = "str";
    
        private final Selection<Y> selection;
    
        public StrFunction(CriteriaBuilder criteriaBuilder, Selection<Y> selection) {
            super((CriteriaBuilderImpl) criteriaBuilder, String.class, FCT_NAME);
            this.selection = selection;
        }
    
        @Override
        public void registerParameters(ParameterRegistry registry) {
            Helper.possibleParameter(selection, registry);
        }
    
        @Override
        public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
            return FCT_NAME + '(' + ((Renderable) selection).render(renderingContext) + ')';
        }
    }

    und dann:

    cb.like(new StrFunction<Long> (cb, root.get(MyObject_.id)), "%mySearchTerm%");

Kostenlose Online-Tests