@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”。
因此,我尝试在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的建议,我在UserDetails类中的"user"成员上方放置了@OnDelete注释,并且这对于OneToOne关系起到了作用,删除级联,但是OnUpdate仍然设置为Restrict,这让我想到了第一个问题 - 这是什么意思呢?我的意思是,“OnDelete”非常简单明了-当我删除父对象时,也删除子对象,但是“OnUpdate”选项的含义是什么?如果将其设置为restrict/cascade,它会如何影响我的应用程序?
我的第二个问题涉及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<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);
角色只是一个枚举,不是实体,因此我无法从角色指向父实体。在这种情况下,是否有一种方法可以级联删除?
Role
是可嵌入对象吗? - Angel Villalain