如何在不删除整个实体的情况下删除外键

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)

@OnDeletehibernate 特定注释。

编辑 2:

如果上面提供的 none 解决方案有效,那么您还可以考虑制作一个 javax.persistence.@PreRemove 注释方法,手动将每个相关 Accountauthor 字段设置为无效的。您将此方法放在 Author class 中。在删除实体之前,用 @PreRemove 注释的方法将始终 运行 。因此,对于 Author,您可以使用以下方法将所有 author_id 字段设置为空。

@PreRemove
public void deleteAuthor(){
   this.getAccounts().forEach(account -> account.setAuthor(null));
}