Search code examples
javahibernatejpaquarkusjpastreamer

Java Quarkus JPA Streamer: Cannot compare left expression of type 'java.lang.Integer' with right expression of type 'java.lang.Object'"


What is this error? I'm new to Java quarkus, thus. seeking assistance regarding this error. I'm trying to get the Film records via its Id. But i cannot, this is my error, can someone help me there please?

I'm just following the tutorial of freecodecamp at youtube, but it seems it is already outdated.

Java quarkus with JPA streamer

The error is at FilmRepository. Because if i make a query like description starts with letter A, I got the result.

FilmRepository:

package org.app.model.repository;

import com.speedment.jpastreamer.application.JPAStreamer;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.app.model.Film;
import org.app.model.Film$;

import java.util.Optional;

@ApplicationScoped
public class FilmRepository implements PanacheRepository  {
    @Inject
    JPAStreamer jpaStreamer;

    public Optional<Film> getFilm(Integer filmId) {
        return jpaStreamer.stream(Film.class)
                .filter(Film$.filmId.equal(filmId))
                .findFirst();
    }
}

Film:

package org.app.model;

import jakarta.persistence.*;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Entity
@Table(name = "film", schema = "sakila")
public class Film implements Serializable {

    public Film() {}

    public Film(Integer filmId, String title, short length) {
        this.filmId = filmId;
        this.title = title;
        this.length = length;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "film_id", nullable = false, updatable = false, columnDefinition = "smallint(5)")
    private Integer filmId;
    @Basic
    @Column(name = "title")
    private String title;
    @Basic
    @Column(name = "description")
    private String description;
    @Basic
    @Column(name = "language_id")
    private short languageId;
    @Basic
    @Column(name = "original_language_id")
    private Short originalLanguageId;
    @Basic
    @Column(name = "rental_duration")
    private short rentalDuration;
    @Basic
    @Column(name = "rental_rate", columnDefinition = "decimal(4,2)")
    private Float rentalRate;
    @Basic
    @Column(name = "length")
    private Short length;
    @Basic
    @Column(name = "replacement_cost")
    private BigDecimal replacementCost;
    @Basic
    @Column(name = "rating", columnDefinition = "enum('G', 'PG', 'PG-13', 'R', 'NC-17')")
    private String rating;
    @Basic
    @Column(name = "special_features", columnDefinition = "set('Trailers', 'Commentaries', 'Deleted Scenes', 'Behind the Scenes')")
    private String specialFeatures;
    @Basic
    @Column(name = "last_update")
    private Timestamp lastUpdate;
    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    @JoinTable(
            name = "film_actor",
            joinColumns = { @JoinColumn(name = "film_id") },
            inverseJoinColumns = { @JoinColumn(name = "actor_id") }
    )
    private List<Actor> actors = new ArrayList<>();

    public Integer getFilmId() {
        return filmId;
    }

    public void setFilmId(Integer filmId) {
        this.filmId = filmId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public short getLanguageId() {
        return languageId;
    }

    public void setLanguageId(short languageId) {
        this.languageId = languageId;
    }

    public Short getOriginalLanguageId() {
        return originalLanguageId;
    }

    public void setOriginalLanguageId(Short originalLanguageId) {
        this.originalLanguageId = originalLanguageId;
    }

    public short getRentalDuration() {
        return rentalDuration;
    }

    public void setRentalDuration(short rentalDuration) {
        this.rentalDuration = rentalDuration;
    }

    public Float getRentalRate() {
        return rentalRate;
    }

    public void setRentalRate(Float rentalRate) {
        this.rentalRate = rentalRate;
    }

    public Short getLength() {
        return length;
    }

    public void setLength(Short length) {
        this.length = length;
    }

    public BigDecimal getReplacementCost() {
        return replacementCost;
    }

    public void setReplacementCost(BigDecimal replacementCost) {
        this.replacementCost = replacementCost;
    }

    public String getRating() {
        return rating;
    }

    public void setRating(String rating) {
        this.rating = rating;
    }

    public String getSpecialFeatures() {
        return specialFeatures;
    }

    public void setSpecialFeatures(String specialFeatures) {
        this.specialFeatures = specialFeatures;
    }

    public Timestamp getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Timestamp lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Film film = (Film) o;
        return filmId == film.filmId && languageId == film.languageId && rentalDuration == film.rentalDuration && Objects.equals(title, film.title) && Objects.equals(description, film.description) && Objects.equals(originalLanguageId, film.originalLanguageId) && Objects.equals(rentalRate, film.rentalRate) && Objects.equals(length, film.length) && Objects.equals(replacementCost, film.replacementCost) && Objects.equals(rating, film.rating) && Objects.equals(specialFeatures, film.specialFeatures) && Objects.equals(lastUpdate, film.lastUpdate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(filmId, title, description, languageId, originalLanguageId, rentalDuration, rentalRate, length, replacementCost, rating, specialFeatures, lastUpdate);
    }

    public List<Actor> getActors() {
        return actors;
    }

    public void setActors(List<Actor> actors) {
        this.actors = actors;
    }
}

FilmResource: package org.app.model;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.app.model.repository.FilmRepository;

import java.util.Optional;

@Path("/")
public class FilmResource {

    @Inject
    FilmRepository filmRepository;

   @GET
    @Path("/film/{filmId}")
    @Produces(MediaType.TEXT_PLAIN)
    public String getFilm(Integer filmId) {
       Optional<Film> film = filmRepository.getFilm(filmId);
       return film.isPresent() ? film.get().getTitle() : "No film was found!";
   }
}

Generate-sources -> Film$:

 public static final ComparableField<Film, Integer> filmId = ComparableField.create(
        Film.class,
        "filmId",
        Film::getFilmId,
        false
    );

Full error:

{
    "details": "Error id 110fe603-9398-457d-85d0-f005c4979fab-1, org.hibernate.query.SemanticException: Cannot compare left expression of type 'java.lang.Integer' with right expression of type 'java.lang.Object'",
    "stack": "org.hibernate.query.SemanticException: Cannot compare left expression of type 'java.lang.Integer' with right expression of type 'java.lang.Object'\r\n\tat org.hibernate.query.sqm.internal.TypecheckUtil.assertComparable(TypecheckUtil.java:358)\r\n\tat org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate.<init>(SqmComparisonPredicate.java:48)\r\n\tat org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate.<init>(SqmComparisonPredicate.java:34)\r\n\tat org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.equal(SqmCriteriaNodeBuilder.java:2143)\r\n\tat org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.equal(SqmCriteriaNodeBuilder.java:190)\r\n\tat com.speedment.jpastreamer.criteria.standard.internal.predicate.DefaultPredicateMapper.lambda$equal$4(DefaultPredicateMapper.java:100)\r\n\tat com.speedment.jpastreamer.criteria.standard.internal.predicate.DefaultPredicateMapper.typeMapping(DefaultPredicateMapper.java:608)\r\n\tat com.speedment.jpastreamer.criteria.standard.internal.predicate.DefaultPredicateMapper.equal(DefaultPredicateMapper.java:96)\r\n\tat com.speedment.jpastreamer.criteria.standard.internal.predicate.DefaultPredicateMapper.mapPredicate0(DefaultPredicateMapper.java:702)\r\n\tat com.speedment.jpastreamer.criteria.standard.internal.predicate.DefaultPredicateMapper.mapPredicate(DefaultPredicateMapper.java:49)\r\n\tat com.speedment.jpastreamer.criteria.standard.internal.InternalPredicateFactory.createPredicate(InternalPredicateFactory.java:43)\r\n\tat com.speedment.jpastreamer.criteria.standard.StandardPredicateFactory.createPredicate(StandardPredicateFactory.java:31)\r\n\tat com.speedment.jpastreamer.merger.standard.internal.criteria.strategy.FilterCriteriaModifier.lambda$modifyCriteria$0(FilterCriteriaModifier.java:60)\r\n\tat java.base/java.util.Optional.ifPresent(Optional.java:178)\r\n\tat com.speedment.jpastreamer.merger.standard.internal.criteria.strategy.FilterCriteriaModifier.modifyCriteria(FilterCriteriaModifier.java:59)\r\n\tat com.speedment.jpastreamer.merger.standard.internal.criteria.InternalCriteriaMerger.merge(InternalCriteriaMerger.java:71)\r\n\tat com.speedment.jpastreamer.renderer.standard.internal.StandardRenderer.render(StandardRenderer.java:120)\r\n\tat com.speedment.jpastreamer.builder.standard.internal.BaseStreamBuilder.renderResult(BaseStreamBuilder.java:183)\r\n\tat com.speedment.jpastreamer.builder.standard.internal.BaseStreamBuilder.renderAndThenApply(BaseStreamBuilder.java:122)\r\n\tat com.speedment.jpastreamer.builder.standard.internal.StreamBuilder.findFirst(StreamBuilder.java:234)\r\n\tat com.speedment.jpastreamer.autoclose.standard.internal.AbstractAutoClosingBaseStream.finallyClose(AbstractAutoClosingBaseStream.java:95)\r\n\tat com.speedment.jpastreamer.autoclose.standard.internal.AutoClosingStream.findFirst(AutoClosingStream.java:212)\r\n\tat org.app.model.repository.FilmRepository.getFilm(FilmRepository.java:20)\r\n\tat org.app.model.repository.FilmRepository_ClientProxy.getFilm(Unknown Source)\r\n\tat org.app.model.FilmResource.getFilm(FilmResource.java:22)\r\n\tat org.app.model.FilmResource$quarkusrestinvoker$getFilm_aaf8f25445473b98b10d3533096c18270654c608.invoke(Unknown Source)\r\n\tat org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)\r\n\tat io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)\r\n\tat org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)\r\n\tat io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:599)\r\n\tat org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)\r\n\tat org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)\r\n\tat org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)\r\n\tat org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)\r\n\tat org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)\r\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)\r\n\tat java.base/java.lang.Thread.run(Thread.java:1589)"
}

Solution

  • for interim solution, I made the FilmRepository like this:

    public Optional<Film> getFilm(Integer filmId) {
            return jpaStreamer.stream(Film.class)
                    .filter(Film$.filmId.in(filmId))
                    .findFirst();
        }
    

    But it is unclear to me why if .equal() doesn't work