Saya memiliki masalah yang sangat konyol dalam pengujian saya. Saya menggunakan @DataJpaTest untuk menjalankan sejumlah tes sederhana pada repositori sederhana. Saya memiliki entitas bernama Event dan antarmuka repositori yang harus selalu mengembalikan entri terakhir.

Namun, tidak peduli apa yang saya lakukan, saya mendapatkan entri pertama.

@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

}

Yang saya minta melalui JPA:

public interface EventRepository extends JpaRepository<Event, Long> {

    Event findFirstById_OrderByCreationDate_Desc(@Nonnull Long id);

}

Sekarang saya berharap kode ini melakukan hal berikut. Pesan acara berdasarkan tanggal pembuatannya yang berisi stempel waktu yang akurat hingga milidetik, letakkan yang terakhir di atas dan kemudian kembalikan hanya yang terakhir sebagai hasil untuk acara tersebut. Ini tampaknya berfungsi di aplikasi yang sebenarnya. Namun dalam tes, hal berikut terjadi.

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

Hasilnya adalah event3 berisi nilai event1, meskipun event2 memiliki stempel waktu yang lebih baru. Ini membuatku cukup gila. Saya telah mencoba menggunakan saveAndFlush() saat menyimpan, flush() langsung di repositori dan saya telah menempatkan @Cacheable(false) pada kelas entitas itu sendiri untuk memastikan tidak ada hal aneh yang terjadi. Apakah saya melewatkan sesuatu? Bukankah ini harus bekerja seperti yang saya harapkan?

Bagian paling aneh tentang ini adalah bahwa findAll() mengembalikan kedua peristiwa dan bahwa memesan ASC atau DESC tampaknya tidak mengubah apa pun.

0
G_V 10 Maret 2020, 22:36

1 menjawab

Jawaban Terbaik

Cobalah untuk berubah

Event findFirstById_OrderByCreationDate_Desc(@Nonnull Long id);

Untuk

Event findFirstByObserved_IdOrderByCreationDateDesc(@Nonnull Long id);

Itu juga harus berfungsi tanpa garis bawah

Event findFirstByObservedIdOrderByCreationDateDesc(@Nonnull Long id);

Lihat juga: 4.4 .3. Ekspresi Properti dan artikel: SpringData: Property Traversal

Tampaknya dalam kueri Anda, Anda menanyakan tentang Event Id. Garis bawah tampaknya tidak diperlukan karena seharusnya tidak ada ambiguitas: Garis bawah akan berguna jika Anda memiliki, misalnya properti observedId di Event. Menggunakan garis bawah seperti pada opsi pertama (...Observed_Id...) akan menyelesaikan masalah potensial itu.

Saya telah memeriksa kueri sql dan menggunakan garis bawah tidak membuat perbedaan .

1
kasptom 10 Maret 2020, 21:18