简体   繁体   中英

i want to retrieve data from db by email, year and term (semester)

I want to retrieve attendance of current user searching by his email in Attendance table. Next I have to be exact which year and semester attendance i want to retrieve, so i tried do it by entering "Date" as a parameter in controller, in service but it doesn't help. It gave me next

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'attendanceRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.example.demo.Repositories.AttendanceRepository.findAttendanceByEmail(java.lang.String,java.lang.String)! At least 2 parameter(s) provided but only 1 parameter(s) present in query.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1290) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1210) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    ... 32 common frames omitted

Also i tried without parameter, there is my code:

AttendanceController.java

@Autowired
    AttendanceService attendanceService;

    // Get User Attendance
    @RequestMapping(value = "/attendance", method = RequestMethod.GET)
    public List<Attendance> getUserAttendance(@AuthenticationPrincipal MyUserDetails myUserDetails, java.util.Date date) {
        return attendanceService.getUserAttendanceByEmail(myUserDetails.getEmail(), date);
    }

AttendanceRepository.java

public interface AttendanceRepository extends JpaRepository<Attendance, Integer> {
    List<Attendance> findAttendanceByEmail(String email, String year_and_term);
}

AttendanceService.java

@Autowired
    AttendanceRepository attendanceRepository;

    // Finds in attendance table by email of the current user
    public List<Attendance> getUserAttendanceByEmail(String email, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int year = cal.get(Calendar.YEAR);
        int term = cal.get(Calendar.MONTH);

        if (term >= 1 && term <= 5)
            term = 1;
        else if (term >= 9 && term <= 12)
            term = 2;

        String year_and_term = year + "-" + (year+1) + " (" + term + ")";
        System.out.println(year_and_term);
        return attendanceRepository.findAttendanceByEmail(email, year_and_term);
    }

AttendanceEntity.java

@Entity
@Table(name = "attendance")
public class Attendance {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    @ManyToOne
    @JoinColumn(name="subject_id", nullable=false)
    private Subjects subjects;
    private String email;
    private Integer absent;
    private Integer attend;
    private Integer permitted;
    private String year_and_term;

    public Attendance(Integer id, Subjects subjects, String email, Integer absent, Integer attend, Integer permitted, String year_and_term) {
        this.id = id;
        this.subjects = subjects;
        this.email = email;
        this.absent = absent;
        this.attend = attend;
        this.permitted = permitted;
        this.year_and_term = year_and_term;
    }

    public Attendance() {
    }
    // getters and setters..

There is my table Attendance in db:

+----+------------+--------+--------+--------+-----------+---------------+
| id | subject_id | email  | absent | attend | permitted | year_and_term |
+----+------------+--------+--------+--------+-----------+---------------+
|  1 |          1 | damir  |      1 |      1 |         1 | 2019-2020 (2) |
|  2 |          2 | damir  |      0 |      5 |         2 | 2019-2020 (2) |
|  3 |          3 | rapkat |      0 |     10 |         0 | 2019-2020 (2) |
|  4 |          1 | damir  |     10 |     20 |         5 | 2019-2020 (1) |
|  5 |          2 | damir  |      2 |     20 |         0 | 2019-2020 (1) |
+----+------------+--------+--------+--------+-----------+---------------+

Actually you have 2 problems here the first is that you made the Variable name with a spring jpa keyword ie 'and' in your variable name year_and_term, and you clubbed both different values to each other, may be in future you need to query on both year and sem separately then you will be in trouble.

So now you have 2 solutions:-

  1. if you still want to go with clubbed then please refactor the variable name to like yearNterm ie just replace the and with N or something you want. so then your query will be like:-

    List findByEmailAndYearNterm(String email, String year_and_term);

  2. Or you can go by my approach ie separate 2 it to 2 variables like 1 is year and 2 is term then your query will be like:-

    List findByEmailAndYearAndTerm(String email, String year, String term);

You want to get data based on two fields but passing only one. So to make it work make below changes.

  1. Use camel case variable names always (standard practice) year_and_term - yearAndTerm

  2. Rename field with something else, as it might create some issues with jpa queries (AND is a keyword)

  3. Change method call to

    findAllAttendanceByEmailAndYearAndTerm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM