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?
The problem was in the entity's id-class. When I made that id-class static, the whole code worked!
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.