在我的应用程序中的许多情况下,我希望使用@OneToMany和@ManyToOne关系返回数据树。我正在使用@SQLDelete @Where注解实现软删除。我不知道如何防止树返回软删除的孙对象。
例如,我的父实体…
@Entity
@Table(name = "gson_test_parent")
@SQLDelete(sql = "UPDATE gson_test_parent SET deleted = true, deleted_at = now() WHERE id=?")
@Where(clause = "deleted=false")
public class GsonTestParent extends SoftDeletableEntity {
public static final String STATUS_NEW = "new";
public static final String STATUS_ACTIVE = "active";
public static final String STATUS_DISABLED = "disabled";
@Expose
private String name;
@Expose
@OneToMany(fetch = FetchType.EAGER, mappedBy="gsonTestParentId")
private List<GsonTestParentToGsonTestChild> gsonTestParentToGsonTestChild = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<GsonTestParentToGsonTestChild> getGsonTestParentToGsonTestChild() {
return gsonTestParentToGsonTestChild;
}
}
字符串
.我的加入实体.
@Entity
@Table(name = "gson_test_parent_to_gson_test_child")
@SQLDelete(sql = "UPDATE gson_test_parent_to_gson_test_child SET deleted = true, deleted_at = now() WHERE id=?")
@Where(clause = "deleted=false")
public class GsonTestParentToGsonTestChild extends SoftDeletableEntity {
public static final String STATUS_ACTIVE = "active";
public static final String STATUS_DISABLED = "disabled";
@Expose
private Long gsonTestParentId;
@Expose
@Transient
@GsonExcludeBackReference
private GsonTestParent gsonTestParent;
@Expose
@ManyToOne(fetch = FetchType.EAGER)
@Where(clause = "deleted=false")
private GsonTestChild gsonTestChild;
public Long getGsonTestParentId() {
return gsonTestParentId;
}
public GsonTestParent getGsonTestParent() {
return gsonTestParent;
}
public void setGsonTestParent(GsonTestParent gsonTestParent) {
this.gsonTestParent = gsonTestParent;
}
public GsonTestChild getGsonTestChild() {
return gsonTestChild;
}
}
型
...和子实体...
@Entity
@Table(name = "gson_test_child")
@SQLDelete(sql = "UPDATE gson_test_child SET deleted = true, deleted_at = now() WHERE id=?")
@Where(clause = "deleted=false")
public class GsonTestChild extends SoftDeletableEntity {
public static final String STATUS_NEW = "new";
public static final String STATUS_ACTIVE = "active";
public static final String STATUS_DISABLED = "disabled";
@Expose
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
型
仅供参考,这些都扩展了SoftDeletableEntity,看起来像...
@MappedSuperclass
public class SoftDeletableEntity extends BaseEntity {
public SoftDeletableEntity() {
super();
}
@Expose
protected Timestamp deletedAt;
protected Boolean deleted = Boolean.FALSE;
public Timestamp getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(Timestamp deletedAt) {
this.deletedAt = deletedAt;
}
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
}
型
当我找到父实体时...
@GetMapping(path="/{id}")
public ResponseEntity<String> get(@PathVariable Long id) throws BaseException {
Map<String, Object> responseMap = new HashMap<>();
GsonTestParent gsonTestParent = gsonTestParentService.find(id);
responseMap.put("action", "Get");
responseMap.put("message", "Entity retrieved");
responseMap.put("entityType", "GsonTestParent");
responseMap.put("entity", gsonTestParent);
return responseService.success(responseMap);
}
型
我得到子实体(孙子),即使它在数据库中被标记为已删除.
{
"payload": {
"entityType": "GsonTestParent",
"action": "Get",
"message": "Entity retrieved",
"entity": {
"name": "test_parent_1",
"gsonTestParentToGsonTestChild": [
{
"gsonTestParentId": 1,
"gsonTestChild": {
"name": "test_child_1",
"deletedAt": "2022-07-26T04:31:30.000",
"id": 1,
"createdAt": "2022-07-22T07:24:15.000",
"updatedAt": "2022-07-22T07:24:15.000",
"status": "active"
},
"deletedAt": null,
"id": 1,
"createdAt": "2022-07-22T07:57:46.000",
"updatedAt": "2022-07-22T07:57:46.000",
"status": "active"
}
],
"deletedAt": null,
"id": 1,
"createdAt": "2022-07-22T07:23:15.000",
"updatedAt": "2022-07-22T07:23:15.000",
"status": "active"
}
},
"status": "success"
}
型
数据库中的gson_test_child记录
mysql> select * from gson_test_child where id = 1;
+----+---------------------+---------------------+---------------------+---------+--------+--------------+
| id | created_at | updated_at | deleted_at | deleted | status | name |
+----+---------------------+---------------------+---------------------+---------+--------+--------------+
| 1 | 2022-07-22 14:24:15 | 2022-07-22 14:24:15 | 2022-07-26 11:31:30 | 1 | active | test_child_1 |
+----+---------------------+---------------------+---------------------+---------+--------+--------------+
型
一些评论:
- 我显式地引用连接表,而不是使用@JoinTable功能,因为我的应用程序中的许多“连接”表都有我想要公开的其他有意义的字段。
- 我以为GsonTestParentToGsonTestChild.gsonTestChild字段上的@Where注解会消除软删除的子项,但显然不是(或者我做错了什么)。
- 我知道我可以在存储库中创建显式的JOIN FETCH本地查询,它将过滤已删除的孙对象,但这就颠覆了使用注解的理由。
请让我知道如果我可以提供更多的信息。
迈克
3条答案
按热度按时间6qfn3psc1#
尝试将
@Where(clause = "deleted=false")
也添加到集合中。rseugnpd2#
@Christian Beikov,
看起来你是对的。
@Where(clause = "deleted=false")
适用于@OneToMany关系,但不适用于@ManyToOne关系。uurv41yg3#
@Where(clause = "is_deleted = false")
已弃用。您可以使用@SQLRestriction(value = "is_deleted = false")
。