0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

No property {Column} found for type {Entity}エラーが出て、@Queryを使ってみた

Posted at

以下のコードでは、Person EntityにPersonを保存して誕生日の月データが"8月"の人を検索しています。
PersonRepositoryTest.java
    @Test
    void findByBirthdayBetween() {
        givenPerson("martin",10,"A",LocalDate.of(1991,8,15));
        givenPerson("david",9,"B",LocalDate.of(1992,7,1));
        givenPerson("dennis",8,"O",LocalDate.of(1993,1,5));
        givenPerson("sophia",7,"AB",LocalDate.of(1994,6,30));
        givenPerson("benny",6,"A",LocalDate.of(1995,8,30));

        List<Person> result = personRepository.findByMonthOfBirthday(8);

        result.forEach(System.out::println);
    }

Person Entityクラス、birthday Columnをオブジェクトとして保持したいので@Embedded annotationを定義しています。

Person.java
package com.informanaging.project.demo.domain;

import com.informanaging.project.demo.domain.dto.Birthday;
import lombok.*;
import javax.persistence.*;
import java.time.LocalDate;

@Entity
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@Data
public class Person {
    // 省略
    @Embedded 
    private Birthday birthday;
    // 省略
}

Birthday DTO クラス、@Embeddable annotationが定義されています。(Person Entityのbirthdayと紐付け)

Birthday.java
package com.informanaging.project.demo.domain.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Embeddable;

@Embeddable // Entityに所属されている
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Birthday {
    private int yearOfBirthday;
    private int monthOfBirthday;
    private int dayOfBirthday;
}

Repository クラスです。月データを受けて Personをselectします。

PersonRepository.java
package com.informanaging.project.demo.repository;

import com.informanaging.project.demo.domain.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.time.LocalDate;
import java.util.List;

// JpaRepository<Entity, Id>
public interface PersonRepository extends JpaRepository<Person, Long> {    
    List<Person> findByMonthOfBirthday(int monthOfBirthday);
}

それで、テストを実行すると以下のエラーが出てしまいます。
詳細を見ると、monthOfBirthdayはBirthdayクラスには定義されていますが、Person Entityには定義されていないためエラーが発生しています。
image.png

エラーを解消するために、Repository クラスにQuery annotationを定義してあげれば対応できます。
そうすると、Person EntityにmonthOfBirthday Columnを別途定義しなくていいです。

修正後_PersonRepository.java
public interface PersonRepository extends JpaRepository<Person, Long> {
    @Query(value = "select person from Person person where person.birthday.monthOfBirthday =?1")
    List<Person> findByMonthOfBirthday(int monthOfBirthday);
}

Query annotaionを定義し、その中に実行したいSQLを作成します。作成するのはただのSQLではなくJPQLを作成しなければなりません。
普通のSQLだとTableを指定しますが、JPQLはEntityを指定します。?1はパラメータのmonthOfBirthdayです。
上記を見ると、Person Entityをfrom句に指定し、where句は「person Entityで定義しているbirthda dtoのmonthOfBirthdayをゲット!」ということで「person.birthday.monthOfBirthday」を指定します。

テストの結果も正常に検索されます。
image.png

JPQLでパラメータとして"?1"を使いたくない場合は、@Param("A")を定義し、"?1"代わりに"A"を使えばいいです。

修正後_PersonRepository.java
public interface PersonRepository extends JpaRepository<Person, Long> {
    @Query(value = "select person from Person person where person.birthday.monthOfBirthday = :monthOfBirthday")
    List<Person> findByMonthOfBirthday(@Param("monthOfBirthday")int monthOfBirthday);
}
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?