Схема базы данных (MySQL)
Вот соответствующие разделы из моей базы данных. дамп:
Код: Выделить всё
storeКод: Выделить всё
CREATE TABLE `store` (
`store_id` tinyint unsigned NOT NULL AUTO_INCREMENT,
`manager_staff_id` tinyint unsigned NOT NULL,
`address_id` smallint unsigned NOT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`store_id`),
UNIQUE KEY `idx_unique_manager` (`manager_staff_id`),
KEY `idx_fk_address_id` (`address_id`),
CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
Код: Выделить всё
staffКод: Выделить всё
CREATE TABLE `staff` (
`staff_id` tinyint unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`address_id` smallint unsigned NOT NULL,
`store_id` tinyint unsigned NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`username` varchar(16) NOT NULL,
`password` varchar(40),
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`staff_id`),
KEY `idx_fk_store_id` (`store_id`),
KEY `idx_fk_address_id` (`address_id`),
CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Вот классы сущностей Java для Store и Staff:
Код: Выделить всё
Store.javaКод: Выделить всё
@Entity
@Table(schema = "movie", name = "store")
public class Store {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Short id;
@ManyToOne
@JoinColumn(name = "manager_staff_id", nullable = false)
private Staff mainStaff;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "address_id", nullable = false)
private Address address;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "mainStore")
private List staffList;
// other fields...
}
Код: Выделить всё
Staff.javaКод: Выделить всё
@Entity
@Table(schema = "movie", name = "staff")
public class Staff {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Short id;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "address_id", nullable = false)
private Address address;
@ManyToOne
@JoinColumn(name = "store_id", nullable = false)
private Store mainStore;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "mainStaff")
private List stores;
// other fields...
}
При попытке сохранить магазин или персонал я сталкиваюсь со следующим исключением:
Код: Выделить всё
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation:
Caused by: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation:
Код: Выделить всё
store.manager_staff_id- Удаление каскадирования и сохранение объектов вручную (не работает).
- Попытка управлять транзакцией границ, чтобы гарантировать сохранение одного раньше другого, но циклическая зависимость вызывает ту же проблему.
Есть ли способ решить эту проблему в рамках использования Hibernate (без Spring)? Можно ли решить эту проблему исключительно на уровне ORM (сторона Java) без изменения схемы базы данных или ограничений (поскольку это находится вне моего контроля)?
Я ищу рекомендации по:
- Правильная настройка каскадирования, если применимо.
- Альтернативные способы разрешения циклической зависимости с соблюдением ограничений, налагаемых существующая схема MySQL.
Подробнее здесь: https://stackoverflow.com/questions/790 ... -hibernate