Does the query return no results for a 1 minute time difference?
My code looks like
An object
@Entity
public class Transaction {
@Id
private String id;
@Column(nullable = false)
private String name;
@Column(nullable = false, precision = 12, scale = 2)
private BigDecimal amount;
@Column(nullable = false)
private boolean debit;
@Column(nullable = false)
private LocalDateTime date;
@Column(name = "created_at")
private LocalDateTime createdAt;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
private Member member;
Request
@Nonnull
public List<Transaction> getTransactionsForUserMonthAndYear(@Nonnull final Member existingMember, final int month,
final int year) {
final LocalDateTime startDate = LocalDateTime.of(year, month, 1, 0, 0, 0, 0);
final LocalDateTime endDate = startDate.plusMonths(1);
return crudService.query(transaction)
.where(transaction.member.eq(existingMember))
.where(transaction.date.goe(startDate))
.where(transaction.date.lt(endDate))
.list(transaction);
}
and my test looks like
@Test
public void testGetTransactionsDifferentMonths() {
final Member member = new Member("newUser@gmail.com", "userExternalId", "clientId", "clientSecret");
final Category category = new Category("Groceries", "Food & Drink");
crudService.create(member);
crudService.create(category);
jpaRule.changeTransaction();
final LocalDateTime startOfMonth = LocalDateTime.of(2014, Month.JANUARY, 1, 0, 0, 0, 0);
final LocalDateTime nextMonth = startOfMonth.plusMonths(1).plusMinutes(1);
final Transaction sprouts = new Transaction("Sprouts", new BigDecimal("12345.346"), true, startOfMonth, member, category);
final Transaction costco = new Transaction("Costco", new BigDecimal("100.295"), true, nextMonth, member, category);
crudService.create(sprouts);
crudService.create(costco);
jpaRule.changeTransaction();
{
final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 1, 2014);
assertFalse(transactions.isEmpty());
assertEquals(1, transactions.size());
assertEquals(sprouts, transactions.get(0));
}
{
final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 2, 2014);
assertFalse(transactions.isEmpty());
assertEquals(1, transactions.size());
assertEquals(costco, transactions.get(0));
}
}
What do I expect?
I expect that
final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 2, 2014);
should return a transaction costco
, but the result is empty.
I'm not sure what is wrong with this request
UPDATE
I have tried some things
- If i do
final LocalDateTime nextMonth = startOfMonth.plusMonths (1) .plusMinutes (1);
The request fails.
final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 2, 2014);
assertFalse(transactions.isEmpty());
which means no transactions for February
- If i do
final LocalDateTime nextMonth = startOfMonth.plusMonths(1).plusHours(1);
Unable to execute
final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 1, 2014);
assertFalse(transactions.isEmpty());
assertEquals(1, transactions.size());
with a mistake
java.lang.AssertionError:
Expected :1
Actual :2
- and if i do
final LocalDateTime nextMonth = startOfMonth.plusMonths(1).plusDays(1);
All passing the test!
It totally blew my mind, I don't know how it works here.
source to share
Have you tried these tips https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa ? Namely, write and register a custom jpa converter for mapping between new date api and java.sql classes.
source to share
I think adding @Temporal (TemporalType.TIMESTAMP) should solve this problem.
Based on the exception you got when trying Temporal
There is an article regarding using Java8 with JPA
https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa
Based on the article.
You need to create AttributeConverter
@Converter(autoApply = true)
public class LocalDateTimePersistenceConverter implements AttributeConverter {
@Override
public java.sql.Timestamp convertToDatabaseColumn(LocalDateTime entityValue) {
return Timestamp.valueOf(entityValue);
}
@Override
public LocalDateTime convertToEntityAttribute(java.sql.Timestamp databaseValue) {
return databaseValue.toLocalDateTime();
}
}
Here is a sample project
source to share