gpt4 book ai didi

mysql - 在 Mysql 上使用 ddl 模式生成时未生成 ON DELETE CASCADE 选项

转载 作者:可可西里 更新时间:2023-11-01 06:46:03 24 4
gpt4 key购买 nike

在运行在 Tomcat 网络应用程序上的 Maven-Spring-Hibernate-MySql 中,我使用 hibernate ddl 通过 MySQL5InnoDBDialect 生成我的数据库模式。

模式生成得很好,除了外键的级联选项。例如我有这个结构:

保存用户详细信息对象的用户对象,两者共享相同的 key :

@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$$

如您所见,“FOREIGN KEY”部分中没有写任何“ON DELETE CASCADE”。

这个问题也有描述herehere

所以我尝试在 userDetails 成员上方添加 @OnDelete 注释,但没有成功。

然后我创建了自己的方言来覆盖 supportsCascadeDelete:

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”:

enter image description here

有没有办法解决这个问题(当然是非手动的)?

更新

正在关注 Angel Villalain的建议我将 @OnDelete 注释放在 UserDetails 类的“用户”成员上方,这对 OneToOne 关系起到了作用,删除是级联的,但 OnUpdate 设置为限制(仍然),这使我想到了我的第一个问题——那是什么意思?我的意思是“OnDelete”非常简单 - 当我删除父级时也删除子级,但是“OnUpdate”选项的含义是什么?当它设置为限制/级联时,它如何影响我的应用程序?

我的第二个问题涉及与 OneToMany 关系的级联。我的 User 类包含许多 UserProvider。以下代码来自 User 类:

@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);

这是 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 选项,但它不是:(我是否正确使用了它?

最后一个问题 - 像@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<Role> roles = new HashSet<Enums.Role>(0);

角色只是一个枚举,而不是实体,因此我无法从角色指向父实体。在这种情况下,有没有办法级联onDelete?

最佳答案

有了 OnDelete 注释,DDL 应该是正确的。您能否检查一下您是如何配置 SessionFactory 的,具体来说,您为 hbm2ddl.auto 参数使用了哪个值。

更新

  • 关于 UserProvider 类的问题。首先映射似乎是双向的,但一侧必须是所有者侧,另一侧必须是反向侧。这意味着拥有关系的一方将关系持久化到连接表中,而另一方必须使用 mappedBy 参数进行映射并且不控制关系。所以 OneToManymappedBy 指向 UserPropertyuser 成员将是反面,并且 UserProperty 将是所有者端,并且应该有 OnDelete 注释。但是让我明天测试一下,以确保我不在我的开发站前。

关于mysql - 在 Mysql 上使用 ddl 模式生成时未生成 ON DELETE CASCADE 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14005442/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com