Hibernate: как обрабатывать "сохранение" временного объекта, который может или не может существовать в базе данных
Это вопрос Hibernate о сохраняющихся временных объектах, которые могут уже существовать в моей базе данных.
Учитывая временный объект (Id является нулевым), который может или не может уже существовать в моей базе данных, и который также имеет уникальный столбец (т. Е. Первичный ключ моего бизнеса, который аннотируется с помощью "unique=true"). Как мне попытаться сохранить его без риска получения ошибки: нарушение ограничения целостности: ограничение уникальности или индекса
Должен ли я предоставлять методы для проверки базы данных на наличие дубликатов, прежде чем пытаться сохранить объект? Что немного расстраивает.
Вот тест, который я выполняю, чтобы попытаться сохранить два идентичных временных объекта...
Вот мой объект:
@Entity
public class ArchivedLicence extends DomainObject implements Licence {
private static final long serialVersionUID = 84973741L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column (unique=true, nullable=false)
private String md5Hash;
@Override
public boolean equals(Object o) {
if(o instanceof ArchivedLicence) {
return md5Hash.equals(((ArchivedLicence)o).md5Hash);
}
return super.equals(o);
}
...
Вот метод сохранения в моем объекте доступа к данным:
@Transactional
@Override
public void saveOrUpdate(ArchivedLicence archivedLicence) {
getCurrentSession().saveOrUpdate(archivedLicence);
//getCurrentSession().save(archivedLicence);
}
Вот мой тест:
//Given the first ArchivedLicence
ArchivedLicence archivedLicence1 = null;
try {
archivedLicence1 = new ArchivedLicence(licenceDao.getByName(internalLicenceName));
} catch (IOException ex) {
Logger.getLogger(OrderTest.class.getName()).log(Level.SEVERE, null, ex);
}
//When it is persisted
archivedLicenceDao.saveOrUpdate(archivedLicence1);
flush();
//Then there should be one ArchivedLicence in the the database
assertEquals(new Long(1), archivedLicenceDao.countAll());
//When a second identical ArchiviedLicence is persisted
ArchivedLicence archivedLicence2 = null;
try {
archivedLicence2 = new ArchivedLicence(licenceDao.getByName(internalLicenceName));
} catch (IOException ex) {
Logger.getLogger(OrderTest.class.getName()).log(Level.SEVERE, null, ex);
}
archivedLicenceDao.saveOrUpdate(archivedLicence2);
flush();
//Then there should still only be one ArchivedLicence in the database
assertEquals(new Long(1), archivedLicenceDao.countAll());
Любая помощь приветствуется, спасибо, Джон
1 ответ
К сожалению, вам придется запросить базу данных, чтобы увидеть, существует ли объект, а затем обновить его, если он есть, и сохранить новый объект, если его нет.
saveOrUpdate не для этой цели - он проверяет идентификатор объекта в памяти, а затем вызывает save, если идентификатор равен нулю, обновляет, если идентификатор не равен нулю.