In Maven-Spring -Hibernate-MySql running on a Tomcat web application, I use hibernate ddl to create my DB schema using MySQL5InnoDBDialect.
The circuit is generated just fine, with the exception of the cascade option for foreign keys. For example, I have this structure:
A user object that contains a user part object, both use the same key:
@Entity @Table(name = "Users") public class User implements Serializable { private static final long serialVersionUID = -359364426541408141L; @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; ... }
And user data:
@Entity @Table(name = "UserDetails") public class UserDetails implements Serializable { private static final long serialVersionUID = 957231221603878419L; @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; ... }
When creating a schema, a foreign key from the user information table to the user table skips cascading.
Here is a diagram for creating custom parts:
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$$
As you can see, in the "FOREIGN KEY" section there is no "ON DELETE CASCADE".
This problem is also described here and here .
So I tried adding the @OnDelete annotation over the userDetails element with no luck.
Then I created my own dialect overriding 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; } }
But still unchanged. The foreign key cascade option is still set to "RESTRICT" after generating the scheme:

Is there a way to solve this problem (of course, not manually)?
UPDATE
Following Angel Villalain's suggestion , I put the @OnDelete annotation above the user member of the UserDetails class, and this did the trick for the OneToOne relationship, deleting is cascading, but OnUpdate is set to restrict (still), which leads me to my first question - what is the point of this ? I mean, "OnDelete" is pretty straight forward - when I delete a parent, I also delete it, but what is the meaning of the "OnUpdate" option? How does this affect my application when it is configured to restrict / cascade?
My second question is about cascading OneToMany relationships. The My User class contains many UserProviders. The following code is from the User class:
@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<UserProvider> userProviders = new HashSet<>(0);
And this is the inverse of the UserProvider class:
@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;
So, after using the @OnDelete annotation, I expected to see the onDelete parameter with a cascade in the connection table, but this is not so :( Did I use it correctly?
The final question is, what about a unidirectional relationship like @ElementCollection? My UserDetails class contains ElementCollection roles (each user can be assigned one or more roles):
@ElementCollection(fetch = FetchType.EAGER, targetClass = Role.class) @CollectionTable(name = "Users_Roles", joinColumns = @JoinColumn(name = "User_Id", referencedColumnName = "User_Id")) @Column(name = "Role") protected Set<Role> roles = new HashSet<Enums.Role>(0);
A role is just an enumeration, not an entity, so I cannot point from a role to a parent. In this case, is there a way to cascade onDelete?