jjzjj

java - 关系表 delete-cascade 在 4 种情况下,但 Entity-config 只允许 2

coder 2024-03-08 原文

我有两个普通表和一个关系表。

 --------------------------------------------------
|  Group         | Membership      | User          |
| (ID, NAME)     |(GRP_ID, U_ID)   |(ID, FORENAME) |
 --------------------------------------------------
|  1,  Admin     | 1,      1       | 1, Joe        |
 --------------------------------------------------

成员(member)有两个外键

FK1 Membership.GRP_ID -> Group.ID
FK2 Membership.U_ID   -> User.ID

我可以为每个外键(FK1FK2)设置 cascade-delete


事实 1

如果 FK1FK2 都没有删除级联,我就不能删除 Admin 和 Joe,因为他们在“成员身份”中保持连接。

CREATE TABLE Membership (
    GRP_ID INT NOT NULL,
    U_ID INT NOT NULL,
    FOREIGN KEY (GRP_ID) REFERENCES Group (id),
    FOREIGN KEY (U_ID) REFERENCES User (id)
);

事实 2

如果 FK1 级联删除但 FK2 没有,您可以删除 Admin(删除成员资格)但不能删除 Joe。

CREATE TABLE Membership (
    GRP_ID INT NOT NULL,
    U_ID INT NOT NULL,
    FOREIGN KEY (GRP_ID) REFERENCES Group (id) ON DELETE CASCADE,
    FOREIGN KEY (U_ID) REFERENCES User (id) 
);

事实 3

如果 FK2 级联删除但 FK1 没有,您可以删除 Joe(删除成员的内容)但不能删除 Admin。

CREATE TABLE Membership (
    GRP_ID INT NOT NULL,
    U_ID INT NOT NULL,
    FOREIGN KEY (GRP_ID) REFERENCES Group (id),
    FOREIGN KEY (U_ID) REFERENCES User (id) ON DELETE CASCADE
);

事实 4

如果FK2级联删除FK1级联删除。删除 Joe 将删除 Membership,但 Admin 保持不变。删除 Admin 将删除 Membership,但 Joe 保持不变。

CREATE TABLE Membership (
    GRP_ID INT NOT NULL,
    U_ID INT NOT NULL,
    FOREIGN KEY (GRP_ID) REFERENCES Group (id) ON DELETE CASCADE,
    FOREIGN KEY (U_ID) REFERENCES User (id) ON DELETE CASCADE
);


组Java代码:

// @formatter:off
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;
import javax.persistence.Column;
import javax.persistence.Version;
import javax.persistence.SequenceGenerator;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import org.hibernate.envers.Audited;
import java.util.LinkedHashSet;
import javax.persistence.OneToMany;
import java.util.Set;
import javax.persistence.OrderBy;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;

@Entity
@Table(name="Group")
@SuppressWarnings("serial")
public class Group implements java.io.Serializable {
  private Integer id;
  private Set<User> users = new LinkedHashSet<>();
  private String name;

  @Id
  @Column(name = "ID", nullable = false)
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen241738")
  @SequenceGenerator(name = "gen241738", sequenceName = "seq_group_id")
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }

  @OrderBy
  @ManyToMany
  @JoinTable(name="Membership", joinColumns = {
    @JoinColumn(name="GRP_ID", referencedColumnName="ID", nullable=false),
  }, inverseJoinColumns = {
    @JoinColumn(name="U_ID", referencedColumnName="ID", nullable=false)
  })
  public Set<User> getUsers() {
    return users;
  }
  public void setUsers(Set<User> users) {
    this.users = users;
  }

  @Column(name = "NAME", nullable = false)
  public String getName() {
    return this.name;
  }
  public void setName(String name) {
    this.name = name;
  }
}
//@formatter:on


问题

当关系表包含两个外键时,将可能性扩展到 2x2=4 情况,为什么注释 @ManyToMany只允许一个删除级联?

最佳答案

When a relationtable contains two foreign keys scaling the possibilitys to 2x2=4 cases, why does the annotation @ManyToMany allows only one delete-cascadation?

级联不仅由类型定义,而且由 relationship 的拥有方定义。 :

Entities that use relationships often have dependencies on the existence of the other entity in the relationship. For example, a line item is part of an order; if the order is deleted, the line item also should be deleted. This is called a cascade delete relationship.

对于 @ManyToMany :

Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side. The join table is specified on the owning side. If the association is bidirectional, either side may be designated as the owning side. If the relationship is bidirectional, the non-owning side must use the mappedBy element of the ManyToMany annotation to specify the relationship field or property of the owning side. The join table for the relationship, if not defaulted, is specified on the owning side.

因此,从您的示例来看,Group 是拥有方,我认为 User 是非拥有方,因此它代表事实 2事实 3 反之亦然。

@Entity
@Table(name="Group")
@SuppressWarnings("serial")
public class Group implements java.io.Serializable {

  @OrderBy
  @ManyToMany
  @JoinTable(name="Membership", joinColumns = {
    @JoinColumn(name="GRP_ID", referencedColumnName="ID", nullable=false),
  }, inverseJoinColumns = {
    @JoinColumn(name="U_ID", referencedColumnName="ID", nullable=false)
  })
  public Set<User> getUsers() {
    return users;
  }
}

如果关联是双向的,则任何一方都可以指定为拥有方。如果这样做,您将代表您的事实 4

对于最后一个示例,您应该将 Mapping 表的 POJO 表示定义为每个关系的拥有方。

我向您展示了没有遗漏的配置/字段,并且所有情况都可以通过指定拥有方来完成。您错误地期望 @ManyToMany 的字段 cascade 进行整个级联配置。


刚刚在评论中发现您实际上是在寻求对级联的解释:

The answer did not help me in understanding what is the matter of cascade=null

使用cascade,您可以指定必须级联到关联目标的操作。级联是由 hibernate 执行的,它不是数据库级别的级联操作。通过上面定义的关系,我们判断与 Group 关联的 User 是否也应该在 Group 执行时保留/合并/删除/刷新/分离(使用适当的类型)或不使用(using cascade=null)。

关于java - 关系表 delete-cascade 在 4 种情况下,但 Entity-config 只允许 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57003509/

有关java - 关系表 delete-cascade 在 4 种情况下,但 Entity-config 只允许 2的更多相关文章

  1. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  2. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  5. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

    我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

  8. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐