查询不返回任何1分钟时差的结果?

时间:2014-11-11 05:41:55

标签: java date jpa querydsl

我的代码看起来像

实体

@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;

查询

    @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);
    }

我的测试看起来像

 @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));
        }
    }

我的期望是什么?
我希望

final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 2, 2014);

应返回costco事务,但结果为空。

我不确定此查询有什么问题

更新

我尝试过某些事情

  • 如果我
  

final LocalDateTime nextMonth =   startOfMonth.plusMonths(1).plusMinutes(1);

查询失败

final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 2, 2014);
            assertFalse(transactions.isEmpty());

表示找不到February

的交易
  • 如果我
final LocalDateTime nextMonth = startOfMonth.plusMonths(1).plusHours(1);

失败
 final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 1, 2014);
            assertFalse(transactions.isEmpty());
            assertEquals(1, transactions.size());  

有错误

java.lang.AssertionError: 
Expected :1
Actual   :2
  • 如果我这样做
final LocalDateTime nextMonth = startOfMonth.plusMonths(1).plusDays(1);

所有测试通过!

这让我大吃一惊,我不知道这里有什么工作

2 个答案:

答案 0 :(得分:2)

您是否尝试过这些建议https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa? 即,写&amp;注册一个jpa自定义转换器来映射新的日期api和java.sql类。

答案 1 :(得分:0)

我认为添加@Temporal(TemporalType.TIMESTAMP)应解决此问题。

基于异常,您在尝试Temporal 时收到的

有一篇关于将Java8与JPA一起使用的文章

https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa

基于文章。

您需要创建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();
    }
}

这是一个示例项目

https://bitbucket.org/montanajava/jpaattributeconverters