Как сравнить класс, аннотированный полем @Entity, без снижения производительности хранения объекта в БД?

У меня есть класс БД, который помечен @Entity в Java.

Я хочу сравнить 2 экземпляра класса, поле которого я хочу сравнить по полям, но получаю ошибку от Hamcrest, что объекты не равны. Он сохраняется, если я автоматически не сгенерирую equals и hashCode в Eclipse.

Структура сущности следующая:

@Entity
@Table(name = "book")
public class Book extends BaseEntity {

  @NotNull
  @Column
  private String title;
}

и

@MappedSuperClass
class BaseEntity {

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

}

Для простоты я опустил все геттеры и сеттеры.

Пример кода, как я использую сущность выше:

public void updateBookTitles(bookIds) {
  List<Book> books = bookRepository.findByBookIds(bookIds);

  books.forEach((book) -> {
    book.setTitle("Example: " + book.getTitle());
  });
  bookRepository.saveAll(books);
}

При тестировании этого:

@Test
public void updateSingleBookTitle() {
    Book book = new Book();
    book.setId(1L);
    book.setTitle("Stack Overflow manual");

    when(bookRepository.findByBookIds(Arrays.asList(1L))).thenReturn(Arrays.asList(book));

    updateBookTitles(Arrays.asList(1L));

    Book expectedBook = new Book();
    expectedBook.setId(1L);
    expectedBook.setTitle("Stack Overflow manual");

    verify(bookRepository, times(1)).saveAll(Arrays.asList(expectedBook))
}

Поэтому вопрос у меня. Есть ли способ, кроме автогенерации equals и hashCode, чтобы объекты были равны при тестировании, а также, чтобы не снижалась производительность при сохранении в БД. Насколько я понимаю, на данный момент объекты проверяются по полю id не по всем полям.

добавьте пример кода, где создайте/сравните эти объекты

Vlad Hanzha 18.02.2019 16:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
36
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать что-то вроде Lombok https://projectlombok.org/ для таких объектов данных. Как и равные, hashCode, геттеры и сеттеры.

Ответ принят как подходящий

Вы можете использовать метод samePropertyValuesAs:

Book book1 = new Book();
Book book2 = new Book();
assertThat(book1, samePropertyValuesAs(book2));

Это будет сравнивать ваши объекты поле за полем и выполнять утверждения об их равенстве друг другу. Если вам нужно игнорировать какие-то поля - смотрите Shazamcrest — многоразовые сопоставители Hamcrest, подходящие для автоматизированного тестирования.


ОБНОВЛЕНИЕ 1:

Попробуйте использовать следующий код:

verify(bookRepository, times(1)).saveAll(argThat(new ArgumentMatcher<List<Book>>() {
            @Override
            public boolean matches(Object argument) {
                List<Book> bookToCheck = (List<Book>) argument;
                assertThat(bookToCheck.get(0), sameAsBean(expectedBook));
                return true;
            }
        }));

Дополнительная информация : ArgumentMatcher

Другие вопросы по теме