java - JPA @JoinTable - 三个 ID 列

标签 java hibernate unique-constraint multiple-columns join

我的情况与此问题图表中概述的情况非常相似:JPA. JoinTable and two JoinColumns , 尽管有不同的问题。

我有三个表:FunctionGroupLocation。目前,我使用 @JoinTableLocationGroup 之间设置了一个连接表。两边都是 @ManyToMany,并且工作得很好。

我试图添加一个约束,即任何 Location 都不应与多个具有相同 FunctionGroup 相关联。因此,我在 SQL 架构中的连接表中为 Function 添加了一列,并在 LocationFunction 列中添加了唯一性约束,如下所示:

create table function_table (
  id varchar(50),
  primary key(id)
);

create table group_table (
  id varchar(50),
  function_id varchar(50) not null,
  primary key(id)
);

alter table group_table add constraint FK_TO_FUNCTION foreign key (function_id) references function_table;

create table location_table (
  id varchar(50),
  primary key(id)
);

create table group_location_join (
  location_id varchar(50) not null,
  group_id varchar(50) not null,
  function_id varchar(50) not null,
  primary key(location_id, group_id, function_id),
  unique(location_id, function_id)
);

alter table group_location_join add constraint FK_TO_LOCATION foreign key (location_id) references location_table;
alter table group_location_join add constraint FK_TO_GROUP foreign key (group_id) references group_table;
alter table group_location_join add constraint FK_TO_FUNCTION foreign key (function_id) references function_table;

然后我尝试在我的模型实体中设置以下内容:

@Entity
@Table(name = "function_table")
public class Function {
  @Id
  @Column(name = "id", length = 50)
  private String id;
}

@Entity
@Table(name = "group_table")
public class Group {
  @Id
  @Column(name = "id", length = 50)
  private String id;

  @ManyToOne
  @JoinColumn(name = "function_id", referencedColumnName = "id", nullable = false)
  private Function function;

  @ManyToMany
  @JoinTable(name = "group_location_join",
    joinColumns = {@JoinColumn(name = "group_id", referencedColumnName = "id"),
                   @JoinColumn(name = "function_id", referencedColumnName = "function_id")},
    inverseJoinColumns = @JoinColumn(name="location_id", referencedColumnName = "id"))
  private Set<Location> locations;
}

@Entity
@Table(name = "location_table")
public class Location {
  @Id
  @Column(name = "id", length = 50)
  private String id;

  @ManyToMany
  @JoinTable(name = "group_location_join",
    joinColumns = @JoinColumn(name="location_id", referencedColumnName = "id")
    inverseJoinColumns = {@JoinColumn(name = "group_id", referencedColumnName = "id"),
                   @JoinColumn(name = "function_id", referencedColumnName = "function_id")})
  private Set<Group> groups;
}

(显然,这些实体还有更多内容,但我将它们精简为仅与此问题相关的部分。)

这是行不通的。当我编写一个简单的测试来创建与 Group 相关联的 Location 时,该 GroupFunction 相关联,我尝试刷新 session 的那一刻为了提交事务,Hibernate 给了我这个:

java.lang.ClassCastException: my.package.Group cannot be cast to java.io.Serializable

我认为正在发生的事情是 Hibernate 变得很困惑,举起手来说“我会序列化它,将它发送到数据库,希望它知道发生了什么。”

当我添加 implements Serializable 并将 serialVersionUID 添加到 Group 时,我得到了这个:

org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: FUNCTION_ID

此时我不太确定如何继续,或者我是否已经在错误的道路上走得太远了。也许我没有正确考虑 SQL,并且有一种更简单的方法来确保不涉及所有这些荒谬的约束。

编辑:在我的系统中,所涉及表的 DAO 没有保存功能。这意味着只要在数据库中设置了我的约束,我的应用程序就不会在意;它不能插入违反约束的东西,因为它根本不能插入东西。

编辑 2:正如我在第一个编辑中所述,我最初从未解决过所述问题,而是在不触及 Java 代码的情况下简单地在我的数据库模式中添加了第三列> 上面的部分。但我已经尝试使用 @Embedded 复合键创建一个显式连接表对象,它似乎有效。

最佳答案

您正在尝试创建复合主键。在 Hibernate 中,您可以使用 @Embeddable 注释来实现。在下面的示例中,您可以找到为两个实体使用复合键的方法。

我相信您可以继续使用此示例并创建您自己的主键版本。

Mapping ManyToMany with composite Primary key and Annotation:

关于java - JPA @JoinTable - 三个 ID 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14899736/

相关文章:

Java问题解决。这个对吗?

hibernate - 在这种情况下我们需要 Hibernate 映射吗?

java - 如何使用 JPA 规范中的另一个公共(public)实体加入两个实体?

Mysql如何创建EQUAL约束?

java - Kotlin 比 java 更难逆向工程吗

java - 如何通过构建的 jar 正确放置和使用项目资源?

java - Spring中使用依赖注入(inject)替代工厂模式

c# - 在 SQL Server 中跳过完全相同的记录

python - SQLite 中字段的唯一组合?

java - 使用 java 检查 ibatis 中的 isNotEqual 属性