6

I have a basic SpringBoot app. using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file. I have this method defined in a Repository that extends from

CrudRepository<HotelPrice, Long>, PagingAndSortingRepository<HotelPrice, Long> {

This is the method

List<HotelPrice> getByHotelAndUpdateDateGreaterThan (Hotel hotel, Date date, PageRequest pageRequest);

and the service:

public List<HotelPrice> getMonthlyMinPriceDate(Hotel hotel) {
        return hotelPriceRepository.getByHotelAndUpdateDateGreaterThan
                (hotel, DateUtils.monthlyDate(), new PageRequest(1, 1,new Sort(Sort.Direction.DESC, "price")));
    }

But when I run a Junit Test I got this error:

 java.util.NoSuchElementException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042)
at org.springframework.data.jpa.repository.query.CriteriaQueryParameterBinder.bind(CriteriaQueryParameterBinder.java:65)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:101)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:161)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:152)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJpaQuery.java:236)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:157)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:86)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:123)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:87)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:499)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy118.getByHotelAndUpdateDateGreaterThan(Unknown Source)
at com.booking.backend.service.HotelPriceService.getWeeklyMinPriceDate(HotelPriceService.java:85)
at com.booking.backend.service.HotelPriceService$$FastClassBySpringCGLIB$$cabd5c58.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.booking.backend.service.HotelPriceService$$EnhancerBySpringCGLIB$$9dd8e53b.getWeeklyMinPriceDate(<generated>)
at com.booking.HotelPriceServiceTests.testGetWeeklyMaxPriceDate(HotelPriceServiceTests.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)Hotel
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)

Would be possible to return an empty list instead of a null ????

I also set the app. property spring.jpa.properties.hibernate.format_sql=true

But I don't see that any sql in the console

@Entity
@Table(name="t_Hotel_price")
public class HotelPrice implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public HotelPrice() {
    }


    public HotelPrice(Hotel Hotel) {
        this.Hotel = Hotel;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;


    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "Hotel_id")
    Hotel Hotel;

    float price;

    @Column(name = "update_date")
    private Date updateDate;

    public Hotel getHotel() {
        return Hotel;
    }

    public void setHotel(Hotel Hotel) {
        this.Hotel = Hotel;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }



    public Long getId() {
        return id;
    }


    public void setId(Long id) {
        this.id = id;
    }


    public Date getUpdateDate() {
        return updateDate;
    }


    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }


    @Override
    public String toString() {
        return "HotelPrice [Hotel=" + Hotel + ", price=" + price + ", updateDate=" + updateDate + "]";
    }
}

and

@Entity
@Table(name="t_Hotel")
public class Hotel  implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;    

    private String HotelId;

    private String symbol;

    private float histMaxPrice;

    private int numMaxPriceEvents=0;

    @Column(name = "update_date")
    @Convert(converter = LocalDateTimeAttributeConverter.class)
    private LocalDateTime histMaxPriceDate;

    @OneToMany(mappedBy="Hotel", fetch=FetchType.LAZY, orphanRemoval=true)
    private List<HotelDailyPrice> dailyPrice;

    @OneToMany(mappedBy="Hotel", fetch=FetchType.LAZY, orphanRemoval=true)
    private List<HotelPrice> price;

    @OneToMany(mappedBy="Hotel", fetch=FetchType.LAZY, orphanRemoval=true)
    private List<HotelPriceSummary> summary;


    public Hotel() {
        super();
    }

    public Hotel(String HotelId) {
        super();
        this.HotelId = HotelId;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getHotelId() {
        return HotelId;
    }

    public void setHotelId(String HotelId) {
        this.HotelId = HotelId;
    }

    public float getHistMaxPrice() {
        return histMaxPrice;
    }

    public void setHistMaxPrice(float histMaxPrice) {
        this.histMaxPrice = histMaxPrice;
    }

    public LocalDateTime getHistMaxPriceDate() {
        return histMaxPriceDate;
    }

    public void setHistMaxPriceDate(LocalDateTime histMaxPriceDate) {
        this.histMaxPriceDate = histMaxPriceDate;
    }

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((HotelId == null) ? 0 : HotelId.hashCode());
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Hotel other = (Hotel) obj;
        if (HotelId == null) {
            if (other.HotelId != null)
                return false;
        } else if (!HotelId.equals(other.HotelId))
            return false;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Hotel [id=" + id + ", HotelId=" + HotelId + ", histMaxPrice=" + histMaxPrice
                + ", histMaxPriceDate=" + histMaxPriceDate + "]";
    }

    public int getNumMaxPriceEvents() {
        return numMaxPriceEvents;
    }

    public void setNumMaxPriceEvents(int numMaxPriceEvents) {
        this.numMaxPriceEvents = numMaxPriceEvents;
    }

    public List<HotelDailyPrice> getDailyPrice() {
        return dailyPrice;
    }

    public void setDailyPrice(List<HotelDailyPrice> dailyPrice) {
        this.dailyPrice = dailyPrice;
    }

    public List<HotelPrice> getPrice() {
        return price;
    }

    public void setPrice(List<HotelPrice> price) {
        this.price = price;
    }

    public List<HotelPriceSummary> getSummary() {
        return summary;
    }

    public void setSummary(List<HotelPriceSummary> summary) {
        this.summary = summary;
    }
}

I also tried to use Page<HotelPrice> but then I got the error:

Paging query needs to have a Pageable parameter!

This is the function DateUtils.monthlyDate()

LocalDate now = LocalDate.now().minusDays(numDaysToSubstract); return Date.from(now.atStartOfDay(ZoneId.systemDefault()).toInstant());

3
  • There is support for Optional. You can change your return type to be Optional<List<HotelPrice>>. This way you can check if the value is present or not Commented Feb 28, 2018 at 14:52
  • 13
    the repository never returns null but always an empty list! Have a closer look at the stack trace. the exceptions is thrown in the Parameter binding phase. there mus be something wrong with the arguments. Commented Feb 28, 2018 at 15:08
  • Can you post HotelPrice and Hotel model? Commented Mar 3, 2018 at 10:23

2 Answers 2

3

I have noticed few thing in the question: (update the answer)

  1. No need to extends both CrudRepository<HotelPrice, Long>, PagingAndSortingRepository<HotelPrice, Long>. PagingAndSortingRepository<HotelPrice, Long> internally extends CrudRepository<HotelPrice, Long>.
  2. Instead of passing the entire Hotel object you can pass only primary key of Hotel (id). Below given the syntax for it: Page<HotelPrice> getByHotelIdAndUpdateDateGreaterThan (Long id, Date date, Pageable pageable);. You can send the PageRequest from service but you must have Pageable in Repository.
  3. When you use pagination, you won't get the response as List<HotelPrice>, Instead of that you will get the Page<HotelPrice> object. To extract the List<HotelPrice> use the below: List<HotelPrice> hotelPrice = hotelPricePage.get().getContent();.
Sign up to request clarification or add additional context in comments.

4 Comments

I did it, but I got the error: Paging query needs to have a Pageable parameter!
@EnNuNYetdeCanCalÇadA I have updated the answer. please check it.
still got Paging query needs to have a Pageable parameter!
Yes, you have to use Pageable object in repository layer but in service layer you have to pass PageRequest object. In Service: hotelPriceRepository.getByHotelIdAndUpdateDateGreaterThan (hotelId, DateUtils.monthlyDate(), new PageRequest(1, 1,new Sort(Sort.Direction.DESC, "price"))); and in repository Page<HotelPrice> getByHotelIdAndUpdateDateGreaterThan (Long id, Date date, Pageable pageable);
0

You should check two things:

  1. What is the method DateUtils.monthlyDate() returning? Is it the same Date as the Date from Your repository method, getByHotelAndUpdateDateGreaterThan (Hotel hotel, Date date, PageRequest pageRequest)?
  2. Do You really want the page number one, and not the first page, which is at index zero? You can check that the page index is zero-based at spring's docs for the PageRequest.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.