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.

+3


source to share


2 answers


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.



+2


source


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

https://bitbucket.org/montanajava/jpaattributeconverters

0


source







All Articles