Опция ON DELETE CASCADE не создается при использовании генерации схемы ddl в Mysql
В Maven-Spring-Hibernate-MySql, запущенном в веб-приложении Tomcat, яЯ использую hibernate ddl для генерации моей схемы БД с MySQL5InnoDBDialect.
Схема генерируется просто отлично, за исключением опции каскада для внешних ключей. Например, у меня есть эта структура:
Пользовательский объект, который содержит объект сведений о пользователе, оба имеют один и тот же ключ:
@Entity
@Table(name = "Users")
public class User implements Serializable {
private static final long serialVersionUID = -359364426541408141L;
/*--- Members ---*/
/**
* The unique generated ID of the entity.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "User_Id")
protected long id;
@Getter
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "user", optional = true)
protected UserDetails userDetails;
...
}
И пользователь-детали:
@Entity
@Table(name = "UserDetails")
public class UserDetails implements Serializable {
private static final long serialVersionUID = 957231221603878419L;
/*--- Members ---*/
/**
* Shared Key
*/
@Id
@GeneratedValue(generator = "User-Primary-Key")
@GenericGenerator(name = "User-Primary-Key", strategy = "foreign", parameters = { @Parameter(name = "property", value = "user") })
@Column(name = "User_Id")
protected long id;
@Getter
@Setter
@OneToOne(optional = false, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User user;
...
}
При создании схемы во внешнем ключе из таблицы сведений о пользователе в таблицу пользователей отсутствует каскад.
Вот схема создания пользовательских деталей:
CREATE TABLE `userdetails` (
`User_Id` bigint(20) NOT NULL,
`Creation_Time` bigint(20) NOT NULL,
`EMail` varchar(128) DEFAULT NULL,
`Enabled` bit(1) NOT NULL,
`First_Name` varchar(15) DEFAULT NULL,
`Last_Name` varchar(25) DEFAULT NULL,
`Password` varchar(64) NOT NULL,
`User_Name` varchar(15) NOT NULL,
PRIMARY KEY (`User_Id`),
UNIQUE KEY `User_Name` (`User_Name`),
UNIQUE KEY `EMail` (`EMail`),
KEY `FKAE447BD7BF9006F5` (`User_Id`),
CONSTRAINT `FKAE447BD7BF9006F5` FOREIGN KEY (`User_Id`) REFERENCES `users` (`User_Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$
Как вы можете видеть, нетт любойНА УДАЛЕННОМ КАСКАДЕ " там написано вИНОСТРАННЫЙ КЛЮЧ" раздел.
Эта проблема также описанаВот а такжеВот также.
Поэтому я безуспешно пытался добавить аннотацию @OnDelete над элементом userDetails.
Затем я создал свой собственный диалект, переопределяющий supportCascadeDelete:
public class MySql5Dialect extends MySQL5InnoDBDialect {
public MySql5Dialect() {
super();
}
@Override
public String getTableTypeString() {
return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
}
@Override
public boolean supportsCascadeDelete() {
return true;
}
}
Но все еще без изменений. Мой параметр каскадирования внешнего ключа все еще установлен на "RESTRICT» после генерации схемы:
Есть ли способ решить эту проблему (не вручную, конечно)?
ОБНОВИТЬСледующийАнхель ВиллалаинЯ предлагаю разместить аннотацию @OnDelete над "пользователь» член класса UserDetails, и это помогло с отношением OneToOne, удаление каскадно, но OnUpdate настроен на ограничение (все еще), что приводит меня к моему первому вопросу - что это значит? Я имею в виду "OnDelete» довольно просто - когда я удаляю родителя, удаляем также и ребенка, но в чем смысл "OnUpdate» вариант? Как это влияет на мое приложение, когда установлено ограничение / каскад?
Мой второй вопрос касается каскадирования с отношением OneToMany. Мой класс User содержит множество UserProviders. Следующий код взят изпользователь учебный класс:
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "Users_Providers", joinColumns = @JoinColumn(name = "User_Id"), inverseJoinColumns = @JoinColumn(name = "Provider_Id"))
protected Set userProviders = new HashSet(0);
И это обратная зависимость отUserProvider учебный класс:
@ManyToOne(fetch = FetchType.LAZY)
@JoinTable(name = "Users_Providers", joinColumns = @JoinColumn(name = "Provider_Id", insertable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "User_Id"))
@OnDelete(action = OnDeleteAction.CASCADE)
protected User user;
Поэтому после использования аннотации @OnDelete я ожидал увидеть параметр onDelete с каскадом в таблице соединений, но это не так.t :( Правильно ли я использовал это?
Последний вопрос - как насчет однонаправленных отношений, таких как @ElementCollection? мойUserDetails класс содержит ElementCollection ролей (каждому пользователю может быть назначена одна или несколько ролей):
@ElementCollection(fetch = FetchType.EAGER, targetClass = Role.class)
@CollectionTable(name = "Users_Roles", joinColumns = @JoinColumn(name = "User_Id", referencedColumnName = "User_Id"))
@Column(name = "Role")
protected Set roles = new HashSet(0);
Роль - это просто перечисление, а не сущность, поэтому я не могу указать от роли к родительской сущности. В этом случае есть ли способ каскадного включения OnDelete?