Search code examples
javahibernatejpaspring-data-jpa

JPA get highest value in column with where condition


I'm using a JpaRepository to access a table in my database. I defined the table through an entity. My goal is, to get the highest value in the wordNumber column. But I also have to distinguish entries by the languageId column. That means that I need a method in my repository, that receives a parameter, which I can use in my query.

Currently my repository method looks like this:

public interface WordRepository extends JpaRepository<Word, Word.WordId>
{
    @Query(value = "SELECT MAX(wordNumber) FROM Word WHERE languageId = :languageId")
    Optional<Long> getHighestId(@Param("languageId") Long languageId);
}

And the entity looks like this:

@Data
@Entity
@IdClass(Word.WordId.class)
@Table(name = "WORD")
public class Word
{
    @Id
    private Long languageId;
    @Id
    private Long wordNumber;

    private String letters;

    @AllArgsConstructor
    public class WordId implements Serializable
    {
        public Long languageId;
        public Long wordNumber;

        @Override
        public boolean equals(Object o)
        {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            WordId wordId = (WordId) o;
            return Objects.equals(languageId, wordId.languageId) && Objects.equals(wordNumber, wordId.wordNumber);
        }

        @Override
        public int hashCode()
        {
            return Objects.hash(languageId, wordNumber);
        }
    }
}

When I call the method in the repository with languageId=0 and set my hibernate-sql-logging to trace, the produced sql is:

 select max(w1_0.word_number) from word w1_0 where w1_0.language_id=?

And this error is immediately thrown:

org.hibernate.InstantiationException: Unable to locate constructor for embeddable 'io.fi0x.languagegenerator.db.entities.Word$WordId'

How do I have to adjust the sql to make it work? Or is there something in my entity that's wrong?

Solution:

The problem was in the entity's id-class. When I made that id-class static, the whole code worked!


Solution

  • Classes which are Id classes are required to have a no-arg constructor. The error you are getting indicates that the no-arg constructor for class WordId could not be found.

    Adding a no-arg constructor to class WordId should fix your current problem.