如何在不删除整个实体的情况下删除外键
How to remove foreign key without deleting the whole entity
我是 Spring boot 的新手,我希望能够删除 forgein 键的值,如果它的实体被删除而不删除链接到它的整个实体;我在我的例子中解释了一个拥有帐户的人可以同时是作者和玩家,所以如果我删除一个作者,我想删除它在帐户 table 中的引用而不删除整个帐户,因为这帐户仍然可以指向播放器。我在互联网上搜索我找到了 cascadetype 但它会删除整个帐户!
提前致谢!
这是我的实体
@Table(name = "account")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "ID")
private Long id;
@ManyToOne
@JoinColumn(name = "Author")
private Author author;
@ManyToOne
@JoinColumn(name = "Player")
private Player player;
//attributs, getters & setters
}
@Table(name = "player")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Player implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "ID")
private Long id;
//attributs, getters & setters
}
//ma.myapp.usersgestion.domain.Author
@Table(name = "author")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "ID")
private Long id;
@OneToMany(mappedBy = "author")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@JsonIgnoreProperties(value = { "player", "author"}, allowSetters = true)
private Set<Account> accounts = new HashSet<>();
//attributs, getters & setters
}
更新
我正在使用 jhipster(spring 使用 React 启动)和 h2 数据库(具有基于磁盘的持久性)
//AuthorResource.java
@RestController
@RequestMapping("/api")
@Transactional
public class AuthorResource {
private final Logger log = LoggerFactory.getLogger(AuthorResource.class);
private static final String ENTITY_NAME = "author";
@Value("${jhipster.clientApp.name}")
private String applicationName;
private final AuthorRepository authorRepository;
public AuthorResource(AuthorRepository authorRepository) {
this.authorRepository = authorRepository;
}
/**
* {@code DELETE /authors/:id} : delete the "id" author.
*
* @param id the id of the author to delete.
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
*/
@DeleteMapping("/authors/{id}")
public ResponseEntity<Void> deleteAuthor(@PathVariable Long id) {
log.debug("REST request to delete Author : {}", id);
authorRepository.deleteById(id);
return ResponseEntity
.noContent()
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString()))
.build();
}
//...
}
//AuthorRepository
@SuppressWarnings("unused")
@Repository
public interface AuthorRepository extends JpaRepository<Author, Long> {}
在您的实体 class 作者中添加以下内容:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "author", cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST })
private Set<Account> accounts;
我从列表中省略了级联类型 CascadeType.REMOVE
。这将防止 Account
在删除相关 Author
实体时也被删除。
编辑:
如果上述解决方案不知何故不起作用,那么您也可以尝试在 accounts
字段上方添加 @OnDelete(action = OnDeleteAction.NO_ACTION)
。
@OnDelete
是 hibernate
特定注释。
编辑 2:
如果上面提供的 none 解决方案有效,那么您还可以考虑制作一个 javax.persistence.@PreRemove
注释方法,手动将每个相关 Account
的 author
字段设置为无效的。您将此方法放在 Author
class 中。在删除实体之前,用 @PreRemove
注释的方法将始终 运行 。因此,对于 Author
,您可以使用以下方法将所有 author_id 字段设置为空。
@PreRemove
public void deleteAuthor(){
this.getAccounts().forEach(account -> account.setAuthor(null));
}
我是 Spring boot 的新手,我希望能够删除 forgein 键的值,如果它的实体被删除而不删除链接到它的整个实体;我在我的例子中解释了一个拥有帐户的人可以同时是作者和玩家,所以如果我删除一个作者,我想删除它在帐户 table 中的引用而不删除整个帐户,因为这帐户仍然可以指向播放器。我在互联网上搜索我找到了 cascadetype 但它会删除整个帐户!
提前致谢! 这是我的实体
@Table(name = "account")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "ID")
private Long id;
@ManyToOne
@JoinColumn(name = "Author")
private Author author;
@ManyToOne
@JoinColumn(name = "Player")
private Player player;
//attributs, getters & setters
}
@Table(name = "player")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Player implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "ID")
private Long id;
//attributs, getters & setters
}
//ma.myapp.usersgestion.domain.Author
@Table(name = "author")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "ID")
private Long id;
@OneToMany(mappedBy = "author")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@JsonIgnoreProperties(value = { "player", "author"}, allowSetters = true)
private Set<Account> accounts = new HashSet<>();
//attributs, getters & setters
}
更新
我正在使用 jhipster(spring 使用 React 启动)和 h2 数据库(具有基于磁盘的持久性)
//AuthorResource.java
@RestController
@RequestMapping("/api")
@Transactional
public class AuthorResource {
private final Logger log = LoggerFactory.getLogger(AuthorResource.class);
private static final String ENTITY_NAME = "author";
@Value("${jhipster.clientApp.name}")
private String applicationName;
private final AuthorRepository authorRepository;
public AuthorResource(AuthorRepository authorRepository) {
this.authorRepository = authorRepository;
}
/**
* {@code DELETE /authors/:id} : delete the "id" author.
*
* @param id the id of the author to delete.
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
*/
@DeleteMapping("/authors/{id}")
public ResponseEntity<Void> deleteAuthor(@PathVariable Long id) {
log.debug("REST request to delete Author : {}", id);
authorRepository.deleteById(id);
return ResponseEntity
.noContent()
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString()))
.build();
}
//...
}
//AuthorRepository
@SuppressWarnings("unused")
@Repository
public interface AuthorRepository extends JpaRepository<Author, Long> {}
在您的实体 class 作者中添加以下内容:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "author", cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST })
private Set<Account> accounts;
我从列表中省略了级联类型 CascadeType.REMOVE
。这将防止 Account
在删除相关 Author
实体时也被删除。
编辑:
如果上述解决方案不知何故不起作用,那么您也可以尝试在 accounts
字段上方添加 @OnDelete(action = OnDeleteAction.NO_ACTION)
。
@OnDelete
是 hibernate
特定注释。
编辑 2:
如果上面提供的 none 解决方案有效,那么您还可以考虑制作一个 javax.persistence.@PreRemove
注释方法,手动将每个相关 Account
的 author
字段设置为无效的。您将此方法放在 Author
class 中。在删除实体之前,用 @PreRemove
注释的方法将始终 运行 。因此,对于 Author
,您可以使用以下方法将所有 author_id 字段设置为空。
@PreRemove
public void deleteAuthor(){
this.getAccounts().forEach(account -> account.setAuthor(null));
}