在Tomcat Web应用程序上运行的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”:

有没有解决此问题的方法(当然是非手动的)?

更新

按照Angel Villalain的建议,我将@OnDelete批注放在UserDetails类的“user”成员上方,这完成了OneToOne关系的技巧,删除操作是级联的,但是OnUpdate设置为限制(仍然),这导致我我的第一个问题-这是什么意思?我的意思是“OnDelete”非常简单-当我删除父项时,也删除子项,但是“OnUpdate”选项的含义是什么?设置为限制/层叠时,它对我的​​应用有何影响?

我的第二个问题是与OneToMany关系进行级联。我的User类拥有许多UserProvider。
以下代码来自用户类:
@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 类包含一个ElementElement角色(可以为每个用户分配一个或多个角色):
@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参数映射并且不控制该关系。因此,带有OneToMany指向mappedByuser成员的UserProperty将是反面,而UserProperty将是所有者端,并且应该有OnDelete批注。但是让我明天进行测试以确定,我不在开发站的前面。
  • 关于mysql - 在Mysql上使用ddl模式生成时未生成ON DELETE CASCADE选项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14005442/

    10-12 07:11