G_V
G_V

Reputation: 2434

Spring jpa doesn't return the correct record for findFirstById_OrderByCreationDate_Desc

I have a very silly problem in my tests. I'm using @DataJpaTest to run a number of simple tests on a simple repository. I have an entity called Event and a repository interface that should always return the last entry.

However, no matter what I do, I get the first entry.

@Entity
@Cacheable(false)
public class Event {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(optional = false)
    private Observed observed;

    private LocalDateTime creationDate;

    //Constructor that sets the observer and timestamp
    //getters and setters

}

Which I query via JPA:

public interface EventRepository extends JpaRepository<Event, Long> {

    Event findFirstById_OrderByCreationDate_Desc(@Nonnull Long id);

}

Now I'd expect this code to do the following. Order the events by their creation date which contains a timestamp accurate to the millisecond, putting the last one on top and then return only the last one as the result for the event. This appears to work in the actual application. But in the tests, the following happens.

@Test
public void createAndFindLastEvent() {
    Event event1 = new Event(observer);
    eventRepository.save(event1);
    Event event2 = new Event(observer);
    eventRepository.save(event2);
    Event event3 = eventRepository.findFirstById_OrderByCreationDate_Desc(observer.getId());
}

The result being that event3 contains the values of event1, even though event2 has a later timestamp. This is driving me quite mad. I've tried using saveAndFlush() while saving, flush() directly on the repository and I've put @Cacheable(false) on the entity class itself to ensure no strange things should happen. Am I missing something? Shouldn't this work as I expect it to?

The weirdest part about this is that a findAll() does return both events and that ordering ASC or DESC seems to change nothing.

Upvotes: 0

Views: 482

Answers (1)

kasptom
kasptom

Reputation: 2458

Try to change

Event findFirstById_OrderByCreationDate_Desc(@Nonnull Long id);

to

Event findFirstByObserved_IdOrderByCreationDateDesc(@Nonnull Long id);

It should also work without the underscore

Event findFirstByObservedIdOrderByCreationDateDesc(@Nonnull Long id);

see also: 4.4.3. Property Expressions and the article: SpringData: Property Traversal

It seems that in your query you are asking about the Event's Id. The underscores seem to be not necessary as there should be no ambiguity: They would be useful if you hadd, for example observedId property in the Event. Using the underscore like in the first option (...Observed_Id...) would solve that potential issue.

I've checked the sql queries and using the underscore does not make the difference.

Upvotes: 1

Related Questions