JPA: Nach String statt Primärschlüssel suchen

Tabkas

Mitglied
Abend,

also bei JPA. Mit:

em.find(Tabelle.class, query)

kann man ja suchen, aber eben nur nach Primärschlüsselwerten.

Was, wenn ich nun zB einfach nach einem Wert suchen will? Also eine SELECT WHERE LIKE Abfrage senden will, aber eben mit JPA?

Google gab mir sowas wie:

@Query("SELECT u.username FROM User u WHERE u.username LIKE CONCAT('%',:username,'%')")
List<User> findByUserLike(String user);

Ich nehme an, das soll in die Entitätsklasse geschrieben werden?
Da kommen bei mir aber nur 2 Fehlermeldungen:
1. This method requires a body instead of a semicolon
2. Query is not an annotation type

Wie kann man also danach suchen?

Ich nutze übrigens EclipseLink.

Ich wäre sehr, sehr dankbar für Hilfe!

Beste Grüße
Tabkas
 
em.find(Tabelle.class, query)
In diesem Fall ist `query` aber keine Query (also javax.persistence.Query) sondern einfach java.lang.Object. Die EntityManager.find(Class, Object) Methode bekommt also die Klasse der zu findenden Entität sowie den Primärschlüssel.

Da kommen bei mir aber nur 2 Fehlermeldungen:
1. This method requires a body instead of a semicolon
2. Query is not an annotation type
Diese Fehlermeldung hat nichts mit JPA zu tun, sondern damit, dass du syntaktisch ungültigen Java-Code erzeugt hast.

Wie kann man also danach suchen?
Ich würde dir erstmal die Suche nach JPA Tutorials (und Java-Grundlagentutorials) empfehlen. Für ersteres z.B. erstmal: https://www.baeldung.com/jpa-queries
 
Danke für die Antwort.

Bei dem verlinkten Artikel wird ja überall reine SQL Syntax in einen Query gepackt außer bei
Criteria API Query
.
Ist es also das, was du empfiehlst? Denn reine SQL Syntax würde ich eher meiden wollen, dafür wählte ich ja JPA.

Grüße
 
Denn reine SQL Syntax würde ich eher meiden wollen, dafür wählte ich ja JPA.
Du kannst ganz getrost JPQL verwenden. JPA spezifiziert diese Sprache und Implementierungen davon enthalten entsprechende Umwandlungen in die Dialekte der verwendeten relationalen SQL-basierten Datenbank. JPA ist ausschließlich für SQL-basierte Datenbanken, somit ist JPQL auch ein durchaus vernünftiger Ansatz, seine Queries zu formulieren.
 
Ich erhalte bei allen Methoden folgenden Fehler:

Code:
[EL Warning]: 2019-10-17 13:41:47.535--UnitOfWork(1958592872)--Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [false], of class [class java.lang.Boolean], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[aktiv-->ANGEBOTE.AKTIV]] with descriptor [RelationalDescriptor(model.Angebote --> [DatabaseTable(ANGEBOTE)])], could not be converted to [class java.lang.Byte].
Exception in thread "main" javax.persistence.PersistenceException: Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [false], of class [class java.lang.Boolean], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[aktiv-->ANGEBOTE.AKTIV]] with descriptor [RelationalDescriptor(model.Angebote --> [DatabaseTable(ANGEBOTE)])], could not be converted to [class java.lang.Byte].
    at org.eclipse.persistence.internal.jpa.QueryImpl.getSingleResult(QueryImpl.java:547)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:400)
    at Test.main(Test.java:42)
Caused by: Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [false], of class [class java.lang.Boolean], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[aktiv-->ANGEBOTE.AKTIV]] with descriptor [RelationalDescriptor(model.Angebote --> [DatabaseTable(ANGEBOTE)])], could not be converted to [class java.lang.Byte].
    at org.eclipse.persistence.exceptions.ConversionException.couldNotBeConverted(ConversionException.java:75)
    at org.eclipse.persistence.internal.helper.ConversionManager.convertObjectToByte(ConversionManager.java:299)
    at org.eclipse.persistence.internal.helper.ConversionManager.convertObject(ConversionManager.java:126)
    at org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform.convertObject(DatasourcePlatform.java:179)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getObjectValue(AbstractDirectMapping.java:620)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1218)
    at org.eclipse.persistence.mappings.DatabaseMapping.readFromRowIntoObject(DatabaseMapping.java:1512)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoObject(ObjectBuilder.java:461)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:1004)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneNormally(ObjectBuilder.java:898)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:851)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:734)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:688)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:795)
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:890)
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:509)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1168)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1751)
    at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
    at org.eclipse.persistence.internal.jpa.QueryImpl.getSingleResult(QueryImpl.java:517)


Angebote sieht folgendermaßen aus (ohner getter setter und imports):

Java:
/**
 * The persistent class for the angebote database table.
 * 
 */
@Entity
@NamedQuery(name="Angebote.findAll", query="SELECT a FROM Angebote a")
public class Angebote implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int angebotsID;

    private byte aktiv;

    private String angebotsURL;

    @Temporal(TemporalType.DATE)
    private Date datum;

    private byte manuellUeberarbeitet;

    private double umsatz;

    private String vertriebskanalAngebotsID;

    //bi-directional many-to-one association to Artikel
    @ManyToOne
    @JoinColumn(name="ArtikelID")
    private Artikel artikel;

    //bi-directional many-to-one association to Vertriebskanaele
    @ManyToOne
    @JoinColumn(name="VertriebskanalID")
    private Vertriebskanaele vertriebskanaele;

    //bi-directional many-to-one association to Lager
    @OneToMany(mappedBy="angebote")
    private List<Lager> lagers;

    //bi-directional many-to-one association to Verkaeufe
    @OneToMany(mappedBy="angebote")
    private List<Verkaeufe> verkaeufes;


Die Fehlermeldung sagt, es gäbe einen Konvertierungsfehler von boolesch zu byte. Wo kommt aber boolesch her?

Das Programm zum ausführen ist folgendes Testprogramm:


Java:
        double umsatz = 17.99;
        
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("...");
        EntityManager em = emf.createEntityManager();
        
            CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
            
            CriteriaQuery<Angebote> criteriaQuery = criteriaBuilder.createQuery(Angebote.class);
            
            Root<Angebote> userRoot = criteriaQuery.from(Angebote.class);
            
            Angebote queryResult = em.createQuery(criteriaQuery.select(userRoot)
                                      .where(criteriaBuilder.equal(userRoot.get("umsatz"), umsatz)))
                                      .getSingleResult();


Ich weiss nicht woher boolean kommt. Ich habe die booleschen Werte als tinyint also als byte in die Tabellen eingetragen:
private byte aktiv;

Könnt ihr da helfen?

Wenn ihr mehr Infos benötigt sagt bitte Bescheid!

Vielen Dank!!
Grüße
 
Zuletzt bearbeitet von einem Moderator:
Warum nimmst du nicht einfach boolean, wenn du boolean brauchst?
In Java musst du kein Byte nutzen, um booleans darzustellen, das Mapping übernimmt JPA
 
Die Entitätsklassen wurden automatisch mit byte erstellt.

Meinst du, ich sollte die Datentypen in den Entitätsklassen zu boolean ändern?
 
Update:
Ich habe das nun probiert ("Meinst du, ich sollte die Datentypen in den Entitätsklassen zu boolean ändern?").

Es kommt die Fehlermeldung nicht mehr. Nur die Rückgabe ist null. VIelleicht ist der query falsch, ich schaue ab hier mal selber weiter. Bei Problemen die ich nicht selber lösen kann melde ich nochmal 😀

Vielen Dank soweit!
 

Neue Themen


Zurück
Oben