【问题标题】:Spring Data JPA - Specification querySpring Data JPA - 规范查询
【发布时间】:2021-06-01 02:27:55
【问题描述】:

有一个使用属性表达式的查询:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions:

List<Pupil> findByPupilInClassRoomTeacherName(String name);

尝试通过规范执行查询:

public final class PupilSpecification {
    public static Specification<Pupil> findPupilByTeacherSpecification(String name) {
        return new Specification<Pupil>() {
            @Override
            public Predicate toPredicate(Root<Pupil> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                root = criteriaQuery.from(Pupil.class);
                Join<Pupil, PupilInClassRoom> pupil_PupilInClassRoomJoin = root.join("pupil_id");
                Join<Teacher, PupilInClassRoom> teacher_PupilInClassRoomJoin = pupil_PupilInClassRoomJoin.join("teacher_id");
                return criteriaBuilder.equal(teacher_PupilInClassRoomJoin.get("name"),name);
            }
        };
    }
}

我得到错误:

org.springframework.dao.InvalidDataAccessApiUsageException: Unable to locate Attribute  with the the given name [pupil_id] on this ManagedType [com.SchoolJournal.SpringHibernate.model.BaseModel]; nested exception is java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [pupil_id] on this ManagedType [com.SchoolJournal.SpringHibernate.model.BaseModel]

我做错了什么或忘记添加?

查询:按教师姓名显示所有学生

基础实体:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
abstract class BaseModel {

@Id
@Column(name = "id")
@Getter
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

protected BaseModel() {
  }
}

实体老师:

@Entity
@Table(name = "teacher")
public final class Teacher extends BaseModel {

@OneToOne
@JoinColumn(name = "teacher_id")
private PupilInClassRoom pupilInClassRoom;

@Column(nullable = false)
@Getter
@Setter
private String name;

@Column(nullable = false)
@Getter
@Setter
private String surname;

@Column(nullable = false)
@Getter
@Setter
private String discipline;

public Teacher() {
  }
}

实体瞳:

@Entity
@Table(name = "pupil")
public final class Pupil extends BaseModel {

@OneToOne
@JoinColumn(name = "pupil_id")
private PupilInClassRoom pupilInClassRoom;

@Column(nullable = false)
@Getter
@Setter
private String name;

@Getter
@Setter
@Column(nullable = false)
private String surname;

public Pupil() {

  }
}

实体教室:

@Entity
@Table(name = "class_room")
public final class ClassRoom extends BaseModel {

@OneToOne
@JoinColumn(name = "class_Room_id")
private PupilInClassRoom pupilInClassRoom;

@Column(nullable = false)
@Getter
@Setter
private String name;

public ClassRoom() {
   }
}

实体 PupilInClassRoom:

@Entity
@Table(name = "pupil_in_class_room")
public final class PupilInClassRoom  extends BaseModel {

@OneToOne(mappedBy = "pupilInClassRoom")
@Getter
@Setter
private Pupil pupil;

@OneToOne(mappedBy = "pupilInClassRoom")
@Getter
@Setter
private ClassRoom classRoom;

@OneToOne(mappedBy = "pupilInClassRoom")
@Getter
@Setter
private Teacher teacher;

public PupilInClassRoom() {

}

【问题讨论】:

    标签: java spring spring-data-jpa


    【解决方案1】:
    Join<Pupil, PupilInClassRoom>   pupil_PupilInClassRoomJoin   =
            root.join("pupilInClassRoom");
    Join<PupilInClassRoom, Teacher> teacher_PupilInClassRoomJoin = 
            pupil_PupilInClassRoomJoin.join("teacher");
    

    root.join("pupil_id") -> root.join("pupilInClassRoom")

    Join&lt;Teacher, PupilInClassRoom&gt; -> Join&lt;PupilInClassRoom, Teacher&gt;

    pupil_PupilInClassRoomJoin.join("teacher_id") -> pupil_PupilInClassRoomJoin.join("teacher")

    上面的更新是我猜测需要做你想做的事。可以试试吗?

    【讨论】:

    • 是的,你的回答解决了我的问题)谢谢。 .join (pupilInClassRoom) 和 .join(teacher) 你是怎么做的?
    【解决方案2】:

    问题的解决方法:

    public final class PupilSpecification {
            public static Specification<Pupil> findPupilByTeacherSpecification(String name) {
                return new Specification<Pupil>() {
                    @Override
                    public Predicate toPredicate(Root<Pupil> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                        root = criteriaQuery.from(Pupil.class);
                        Join<Pupil, PupilInClassRoom> pupil_PupilInClassRoomJoin = root.join("pupilInClassRoom");
                        Join<PupilInClassRoom, Teacher> teacher_PupilInClassRoomJoin = pupil_PupilInClassRoomJoin.join("teacher");
                        return criteriaBuilder.equal(teacher_PupilInClassRoomJoin.get(Teacher_.Name),name);
                    }
                };
            }
        }
    

    并添加元模型教师_

    @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
    @StaticMetamodel(Teacher.class)
    public abstract class Teacher_ {
        public static volatile SingularAttribute<Teacher,String> name;
        public static volatile SingularAttribute<Teacher,String> surmane;
        public static volatile SingularAttribute<Teacher,String> discipline;
        public static volatile SingularAttribute<BaseModel,Integer> id;
    
        public static final String Name = "name";
        public static final String Surname = "surname";
        public static final String Discipline = "discipline";
        public static final String Id = "id";
    }
    

    调用规范:

    pupilRepository.findAll(PupilSpecification.findPupilByTeacherSpecification("Alla"))
    

    【讨论】:

      猜你喜欢
      • 2016-07-22
      • 2015-06-03
      • 2014-08-04
      • 2016-02-17
      • 2017-01-12
      • 2019-05-25
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      相关资源
      最近更新 更多