JPA记事本
源:https://blog.ximinghui.org/3b14f3d1/index.html
Cascade
JPA的关系注解,ManyToMany、OneToOne、ManyToOne等,都有一个cascade属性,指向一组CascadeType枚举值。
public enum CascadeType {
ALL, PERSIST, MERGE, REMOVE,REFRESH,DETACH
}
这些值将决定当前操作实体中的另一个实体引用字段,与实际持久化数据不一致时,是否级联更新。
默认等效于空,即 @ManyToMany(cascade = {})
。ALL表示包含所有。具体枚举用处和使用场景去网上查阅,这里不再解释。
JPA实体的生命周期
JPA 实体的生命周期分为四种状态:新建(New/Transient)、托管(Managed)、脱管(Detached)和删除(Removed)。
状态转换图:
新建 ─────persist()────→ 托管 ───remove()───→ 删除
↑ ↑↓
│ │
└──────merge()─────┘
detach()
CascadeType需要注意的点
默认情况下cascade为空,所以不会执行任何关联更新。这种情况下,更新实体时不会关联更新引用实体的信息,即只更新当前实体和实体间的关系(对应数据库中关系表)。常见的场景,如通过HTTP接口接收JSON数据或Spring Data仓库数据初始化,若有如下格式:
[
{
"_class": "org.ximinghui.study.User",
"userId": "8f3e",
"username": "ximinghui",
"password": "123456",
"firstName": "Xi",
"lastName": "Minghui",
"sex": "MALE",
"birthday": "1998-01-01",
"lastLoginTime": "2024-11-04T23:27:31+00:00",
"userGroups": [],
"permissionSets": [
{
"number": 1,
"_remark": "只能在这里添加主键进行关系维护,并不能通过添加权限集的其它属性来实现更新权限集目的",
"name": "New Name",
"permissions": ["ALL_PERMISSIONS"]
}
],
"isEnabled": true
}
]
即使数据中指定了PermissionSet对象的name和permissions属性,JPA也不会更新PermissionSet实体,它只会维护该User实体和number为1的PermissionSet实体间的关系。
但是,如果设置了CascadeType包含级联更新后,如下:
// ...
public class User{
// ...
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) //
private Set<PermissionSet> permissionSets = new LinkedHashSet<>();
// ...
}
这会导致上面的示范JSON数据级联更新PermissionSet实体,因此在设计cascade请考虑到可能存在的安全隐患和意外的实体更新情况!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。