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

Java 查询不返回1分钟时差的任何结果?,java,date,jpa,querydsl,Java,Date,Jpa,Querydsl,我的代码看起来像 @Test public void testGetTransactionsDifferentMonths() { final Member member = new Member("newUser@gmail.com", "userExternalId", "clientId", "clientSecret"); final Category category = new Category("Groceries", "Food &

我的代码看起来像

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

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

@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);
    }
意味着找不到2月份的交易记录

  • 如果我这样做
它至少失败了

final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 2, 2014);
            assertFalse(transactions.isEmpty());
 final List<Transaction> transactions = new TransactionQueries(crudService).getTransactionsForUserMonthAndYear(member, 1, 2014);
            assertFalse(transactions.isEmpty());
            assertEquals(1, transactions.size());  
  • 如果我这样做了
全部通过考试

这完全让我大吃一惊,我不知道这里的情况如何

我认为添加@Temporal(TemporalType.TIMESTAMP)应该可以解决这个问题

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

有一篇文章是关于在JPA中使用Java8的

根据文章

您需要创建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();
    }
}
这里是一个示例项目


你试过这些建议吗?
即,编写并注册一个jpa自定义转换器,以在新的date api和java.sql类之间进行映射。

crudService.create(costco)?实际
assertEquals(萌芽、事务.get(0))
很好,所以我认为这不是一个问题,如果你不增加额外的时间,它就可以工作了?你的粗俗服务会不会把事情搞砸?你能调试一下JPA中的实际日期吗?胡乱猜测,它可能与时区有关。可以添加@Temporal(TIMESTAMP)TIMESTAMP吗。根据代码,似乎不应该这样做,但可能JPA层中有一些配置或其他东西。
原因:org.hibernate.AnnotationException:@Temporal应该只在java.util.Date或java.util.Calendar属性上设置:
当我设置
@Temporal(TemporalType.TIMESTAMP)private LocalDateTime日期时
`谢谢@dna,我使用的是转换器,但好像
autoApply=true
没有按预期工作。我把它改成了私有的LocalDateTime日期,即使使用“final LocalDateTime nextMonth=startOfMonth.plusMonths(1).plusNanos(1);”,情况仍如预期。再次非常感谢
final LocalDateTime nextMonth = startOfMonth.plusMonths(1).plusDays(1);
@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();
    }
}