Java/Hibernate: как я могу вставить определенное значение для столбца с автоинкрементом / @GeneratedValue

У меня есть таблица со столбцом идентификатора, который автоматически увеличивается, и объект Java с геттером, аннотированным @GeneratedValue(strategy = GenerationType.AUTO). Это прекрасно работает при сохранении, однако для модульного теста я хочу указать идентификатор, чтобы он был детерминированным. В MySQL (используемой нами БД) я могу указать значение в операторе вставки, и все работает нормально. Однако, если я установлю поле id в java-объекте и попытаюсь сохранить его, спящий режим выдаст исключение. Как я могу позволить Hibernate указать значение для обычно генерируемого значения?

Пример поля:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
    return this.id;
}

Работает в MySQL:

INSERT INTO myTable (id, str)
VALUES (10,'this works!')

Не работает:

MyObject myObject = new MyObject();
myObject.setId(10L); //remove this line and hibernate saves ok
myObject.setStr("this does not work.");
daoForMyObject.persist(myObject); //throws org.springframework.dao.DataIntegrityViolationException

Заранее спасибо за то, что помогли мне стать хорошим тестировщиком!


person Zugwalt    schedule 10.09.2011    source источник
comment
Об этом уже спрашивали, и есть предлагаемое решение здесь. Надеюсь это поможет. Этот пост был связан с этим вопросом stackoverflow.   -  person Alex Barnes    schedule 11.09.2011


Ответы (1)


Извините, что отвечаю так, как вы, вероятно, не хотите, но я думаю, что ваша идея плоха. Если ваша цель — стать хорошим разработчиком, ориентированным на тестирование, не делайте этого. Вы в основном саботируете то, что хотите проверить. Вы требуете от своего подразделения особого поведения во время тестирования. Но модульный тест должен проверять модуль таким, какой он есть.

Если бы спящий режим позволял вам установить фиксированное значение для поля автоинкремента (или около того), это можно было бы считать ошибкой в ​​спящем режиме. Как я понимаю, хорошо, что hibernate этого не позволяет.

Почему вы не читаете значение id после вызова метода session.save()? Вероятно, ваш daoForMyObject.persist() вызывает save(), так что сразу после этого вы можете прочитать id:

MyObject myObject = new MyObject();
myObject.setStr("this does work.");
daoForMyObject.persist(myObject);
Long id = myObject.getId();

Теперь используйте id для ссылки на вашу сущность вместо 10... почему бы вам не сделать это таким образом?

person Moritz Both    schedule 10.09.2011
comment
На самом деле именно так я начал делать это в своих тестах после публикации этого :-P Но мне все еще любопытно, как явно установить значение поля автоинкремента. MySQL позволяет вам это сделать, было бы неплохо, если бы спящий режим имел такое же поведение, как MySQL - используя автоматическое значение, если оно не указано, в противном случае используйте предоставленное значение. Не думайте, что это будет ошибка. - person Zugwalt; 10.09.2011