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());
Spring JPA Query returns Null instead of List.
You can ignore null fields at the class level by using @JsonInclude(Include. NON_NULL) to only include non-null fields, thus excluding any attribute whose value is null. You can also use the same annotation at the field level to instruct Jackson to ignore that field while converting Java object to json if it's null.
The JPA specification defines that during ordering, NULL values shall be handled in the same way as determined by the SQL standard. The standard specifies that all null values shall be returned before or after all non-null values. It's up to the database to pick one of the two options.
Its findById method retrieves an entity by its id. The return value is Optional<T> . Optional<T> is a container object which may or may not contain a non-null value. If a value is present, isPresent returns true and get returns the value.
I have noticed few thing in the question: (update the answer)
CrudRepository<HotelPrice, Long>, PagingAndSortingRepository<HotelPrice, Long>
. PagingAndSortingRepository<HotelPrice, Long>
internally extends CrudRepository<HotelPrice, Long>
.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.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();
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With