#java #hibernate #unique
#java #гибернация #уникальный
Вопрос:
У меня возникла проблема с гибернацией и принудительным применением уникальных элементов данных при вставке.
Вот мои сокращенные объекты сущностей:
Рабочий процесс:
@Entity
public class Workflow {
private long wfId;
private Set<Service> services;
/** Getter/Setter for wfId */
...
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "workflow_services",
joinColumns = @JoinColumn(name = "workflow_id"),
inverseJoinColumns = @JoinColumn(name = "service_id"))
public Set<Service> getServices() {
return services;
}
Обслуживание:
@Entity
public class Service {
private long serviceId;
private String serviceName;
/** Getter/Setter for serviceId */
...
@Column(unique=true,nullable=false)
public String getServiceName() {
return serviceName;
}
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "service_operations",
joinColumns = { @JoinColumn(name = "serviceId") },
inverseJoinColumns = { @JoinColumn(name = "operationId") })
public Set<Operation> getOperations() {
return operations;
}
Операция:
@Entity
public class Operation {
private long operationId;
private String operationName;
/** Getter/Setter for operationId */
@Column(unique=true,nullable=false)
public String getOperationName() {
return operationName;
}
Моя проблема:
Хотя я указал в каждом объекте, что должно быть уникальным, оно не применяется.
Внутри моего объекта Workflow я поддерживаю набор сервисов. Каждая служба поддерживает список операций. Когда рабочий процесс сохраняется в базе данных, мне нужно, чтобы он проверял, находятся ли службы и операции, которые он использует в настоящее время, уже в базе данных, если да, то связать себя с этими строками.
В настоящее время я получаю повторения в своих таблицах служб и операций.
Я попытался использовать аннотацию: @Table(UniqueConstraints)
но с этим не повезло.
Любая помощь будет с благодарностью
Комментарии:
1. Какую базу данных и диалект вы используете? Как вы создавали таблицы в своей базе данных? hbm2ddl? Можете ли вы показать запросы, используемые для создания вашей таблицы? Я не думаю, что hibernate когда-либо проверяет уникальность сам по себе, но он должен генерировать таблицы с соответствующими уникальными ограничениями в вашей базе данных.
Ответ №1:
Атрибуты unique или UniqueConstraints не используются для обеспечения уникальности в БД, но создают правильный DDL, если вы создаете его из hibernate (и для документации тоже, но это спорно).
Если вы объявляете что-то уникальным в hibernate, вы также должны объявить это в БД, добавив ограничение.
Доведя это до крайности, вы можете создать сопоставление, в котором PK не является уникальным в БД, и hibernate выдаст исключение, когда попытается загрузить один элемент, вызвав Session.load и неожиданно обнаружив, что существует 2 элемента.
Ответ №2:
Внутри моего объекта Workflow я поддерживаю набор сервисов. Каждая служба поддерживает список операций. Когда рабочий процесс сохраняется в базе данных, мне нужно, чтобы он проверял, находятся ли службы и операции, которые он использует в настоящее время, уже в базе данных, если да, то связать себя с этими строками.
Я думаю, вы просите Hibernate обнаруживать повторяющиеся объекты при добавлении их в набор, да? Другими словами, когда вы помещаете объект в набор, вы хотите, чтобы Hibernate искал постоянную версию этого объекта и использовал ее. Однако это не так, как работает гибернация. Если вы хотите, чтобы он «повторно использовал» объект, вы должны сами его найти, а затем использовать. Гибернация этого не делает.
Я бы предложил использовать вспомогательный метод для объекта, подобного DAO, который принимает родительский и дочерний объекты, а затем выполняет поиск и настройку для вас.
Комментарии:
1. Это то, над чем я сейчас работаю. Сейчас моя проблема заключается в том, что Hibernate выдает ошибку при попытке повторного добавления объекта, и я получаю ошибку «дубликат ключа». Я использую ‘session.saveOrUpdate (workflow)’, что приятно, однако я считаю, что это только для самого рабочего процесса, а не для его вспомогательных элементов. т.е. Сервис и операция. Есть мысли?
2. Похоже, вы можете устанавливать отдельные объекты в объект Workflow. Вам нужно извлечь подобъекты (по запросу, идентификатору и т. Д.), А Затем в том же сеансе добавить их в соответствующий набор и сохранить родительский объект. Пока ваше каскадирование настроено правильно, Hibernate должен просто «делать правильные вещи» с подобъектами. Имеет ли это смысл?