@OneToMany @JoinTable 使用三个表

Posted

技术标签:

【中文标题】@OneToMany @JoinTable 使用三个表【英文标题】:@OneToMany @JoinTable usage with three tables 【发布时间】:2018-06-03 10:14:44 【问题描述】:

我在休眠中遇到了一个场景,我尝试寻找这样的场景讨论,但我无法在这里寻求任何建议或帮助,

我有三个表 category , category_artical, artical。

CREATE TABLE `category` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `category_name` varchar(45) NOT NULL,
  `category_description` varchar(45) NOT NULL,
  PRIMARY KEY (`category_id`)
);


CREATE TABLE `article` (
  `article_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(70) NOT NULL,
  `description` varchar(250) NOT NULL,
  `keywords` varchar(150) NOT NULL,
  `content` text NOT NULL,
  PRIMARY KEY (`article_id`)
);

CREATE TABLE `category_article` (
  `category_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  'category_article_status' varchar(1) NOT NULL.
  'category_article_type' varchar(2) NOT NULL,
  PRIMARY KEY (`category_id`,`article_id`),
  UNIQUE KEY `article_id_UNIQUE` (`article_id`),
  KEY `fk_category` (`category_id`),
  KEY `fk_article` (`article_id`),
  CONSTRAINT `fk_article` FOREIGN KEY (`article_id`) REFERENCES `article` (`article_id`),
  CONSTRAINT `fk_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`)
);

我有类别的实体,

    @Entity
    @Table(name = "CATEGORY")
    public class Category 

        private long id;
        private String name;

    @Id
    @GeneratedValue
    @Column(name = "CATEGORY_ID")
    public long getId() 
        return id;
    

    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(
            name = "CATEGORY_ARTICLE",`enter code here`
            joinColumns = @JoinColumn(name = "CATEGORY_ID"),
            inverseJoinColumns = @JoinColumn(name = "ARTICLE_ID")
    )
    private Set<Article> articles; 
    // other getters and setters...

/*For Article entity is */
    @Entity
    @Table(name = "ARTICLE")
    public class Article 
        private long id;
        private String title;
        private String description;
        private String keywords;
        private String content;

    @Id
    @GeneratedValue
    @Column(name = "ARTICLE_ID")
    public long getId() 
        return id;
    

    // other getters and setters...

对于 category_article,我没有实体,因为我在类别中使用 @jointable 所以一切正常,直到我在 category_article 中只有两列,即 category_id 和 article_id。但是,当我再添加两列时,我很困惑如何在那些不为空的列(category_article_status 和 category_article_type)中插入数据。

对此有任何建议。

【问题讨论】:

请告诉我们您的 Java 模型中的其他 2 个字段在哪里?因为 JPA 只是持久化了你的类中的内容,而你的类中没有它们。 它们是 CATEGORY_ARTICLE 表中的新字段,因此我必须找到一种方法从这些新列中插入数据。我上面提到的旧实现。所以这就是我的问题。如何在这些列中插入数据,看到旧实现直接执行 JoinTable 并通过连接插入 category_id 和 article_id。我认为这将改变当前的实现。 “COLUMN”(在表中)不是 FIELD(在类中)。正如我所说......他们不在你的班级。所以把它们放在你的类中,然后你就可以看到它们是如何映射到表格的。如果它们不在 Java 类中,那么可以读取/写入这些列的唯一方法是使用“魔术”。网络上有很多 M-N“归属”排列的例子,例如github.com/datanucleus/samples-jpa/tree/master/… 比利,我完全理解你的观点,我同意,让我给你更详细的解释。所以文章表是一个主表,不应删除其中的任何记录。 CATEGORY_ARTICLE 是一个将 Category 与 ARTICLE 绑定的逻辑表。因此,如果您删除 CATEGORY_ARTICLE 中的任何条目,它也应该删除 Category 表中的主要记录,但不会从 ARTICLE 中删除。下面没有删除功能,现在它们在 CATEGORY_ARTICLE 中增加了两列。所以我目前的设计如上图所示。当你说添加到你的 java 我不能添加到 Article.java 和 Category.java @billy 我必须更改当前的设计,我必须从类别中删除可连接件并像哈迪所说的那样做一些事情。所以我正在研究映射这两列的解决方案,并找到一种方法先从 CATEGORY_ARTICLE 中删除记录,然后从 Category 中删除记录,但仍然不触及 Article 表记录,因为它们不应该被删除。现在我有一个哈迪提到的解决方案,但在这种情况下,在添加它时,它也会在文章表中持续存在,并且当您将其从文章表中删除时,这绝对不会完成。所以我期待嵌入式将解决我的问题。 【参考方案1】:

您应该像这样为CATEGORY_ARTICLE 创建另一个实体。

@Entity
@Table(name = "CATEGORY_ARTICLE")
public class CategoryArticle

   @Id
   private Long id;

   @ManyToOne(cascade = CascadeType.ALL)
   @JoinColumn(name = "category_id")  
   private Category category;

   @ManyToOne(cascade = CascadeType.ALL)
   @JoinColumn(name = "article_id")  
   private Article article; 


   // other columns 
   private Boolean categoryArticleStatus;

   private Long categoryArticleType;


并且还应该更改CategoryArticle。从类别实体中删除JoinTable,并将其更改如下。

类别

@Entity
@Table(name = "CATEGORY")
public class Category 

  //.....

  @OneToMany(mappedBy = "category")
  private Set<CategoryArticle> categoryArticleSet;

文章

@Entity
@Table(name = "ARTICLE")
public class Article 

  //.....

  @OneToMany(mappedBy = "article")
  private Set<CategoryArticle> categoryArticleSet;

 

【讨论】:

所以我应该删除类别条目中的@jointable 吗? Category 实体类有什么变化吗? 好吧,你是说我不能使用 @OneToMany(cascade = CascadeType.ALL) @JoinTable( name = "CATEGORY_ARTICLE", joinColumns = @JoinColumn(name = "CATEGORY_ID"), inverseJoinColumns = @ JoinColumn(name = "ARTICLE_ID") 是的,你应该在CategoryArticle实体中定义两个oneToMany关系。 让我进行这些更改,看看它是如何工作的。除了这些新列之外,现在还需要进行大量更改 所以当 em.persist() 我只需要传递类别对象或类别和文章。因为我必须先在 Category 中插入数据,然后再在 CATEGORY_ARTICLE 中插入数据。根据请求,我得到了 Category 的所有 couln 详细信息以及 article_id。

以上是关于@OneToMany @JoinTable 使用三个表的主要内容,如果未能解决你的问题,请参考以下文章

@oneToMany 和 @JoinTable 在 jpa 中具有唯一约束?

删除元素时使用 JoinTable 和 OrderColumn 的 Hibernate 单向 OneToMany 映射中的约束冲突

码农小汪-Hibernate学习8-hibernate关联关系注解表示@OneToMany mappedBy @ManyToMany @JoinTable

从 Hibernate 中的 JoinTable 中检索所有记录

在哪种情况下使用 JPA @JoinTable 注释?

JPQL 用于单向 OneToMany