【问题标题】:Hibernate One to many mapping override休眠一对多映射覆盖
【发布时间】:2017-11-27 07:18:08
【问题描述】:

在使用休眠的一对多映射中更新连接表时,我遇到了休眠问题。下面是我的两个实体类和连接表实体类。 ArticleCategoryMap.java

    @Entity
    @Table(name = "ARTICLECATEGORYMAP")
    public class ArticleCategoryMap {
    private static final long serialVersionUID = -5653708523600543988L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column ( name = "id")
    Long id;


    @ManyToOne(targetEntity = Article.class, fetch = FetchType.EAGER, optional = true, cascade = CascadeType.PERSIST)
    @JoinColumn(name = "ARTICLE_ID", nullable = true, insertable = true, updatable = true)
    private Article article;


    @ManyToOne(targetEntity = Category.class, fetch = FetchType.EAGER, optional = true, cascade = CascadeType.PERSIST)
    @JoinColumn(name = "CATEGORY_ID", nullable = true, insertable = true, updatable = true)
    private Category category;

   //setter and getter  
}

Article.java

    @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;
    }
   //setter and getter  
    }

Category.java

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

    private long id;
    private String name;

    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(
            name = "ARTICLECATEGORYMAP",
            joinColumns = @JoinColumn(name = "CATEGORY_ID"),
            inverseJoinColumns = @JoinColumn(name = "ARTICLE_ID")
    )
    @CollectionId(
            columns = @Column(name="id"), 
            type=@Type(type="long"), 
            generator = "sequence"
    )
    private Collection<Article> articles;



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

    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(
            name = "ARTICLECATEGORYMAP",
            joinColumns = @JoinColumn(name = "CATEGORY_ID"),
            inverseJoinColumns = @JoinColumn(name = "ARTICLE_ID")
    )
    @CollectionId(
            columns = @Column(name="id"), 
            type=@Type(type="long"), 
            generator = "sequence"
    )
    // setter an getter
    }

现在假设我第一次在文章表中有 2 个元素映射到类别表的一个条目。所以连接表看起来像

现在由于某种原因,我想更新文章条目将映射到新类别 ID 的条目。所以最终的数据库应该看起来像

所以我的问题是如何更新这个连接表。

【问题讨论】:

  • 所以基本上你有一个ManyToMany 关系而不是OneToMany。否则你就不需要 Join-Table
  • 您的映射错误。阅读休眠手册。它对每个集合映射都有示例和解释。您不应该在类别中有 Collection
    。您应该有一个 Collection,并带有 @OneToMany(mappedBy = "category") 注释。或者您可以完全放弃 ArticleCategoryMap 实体,并在 Article 和 Category 之间使用 ManyToMany。

标签: java postgresql hibernate


【解决方案1】:

如果您想要 一对多 关系(1 个类别有很多文章,1 个文章对 1 个类别),您不需要连接表。

实体类应该是这样的:

类别实体:

包含一组文章:

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

    private long id;
    private String name;

    @OneToMany(mappedBy="category")
        private Set<Article> articles;

          ......
    }

文章实体:

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

    @ManyToOne
    @JoinColumn(name="id", nullable=false)
    private Category category;

    private long id;
    private String title;
    private String description;
    private String keywords;
    private String content;

    .......
    }

更多详情请查看hibernate-one-to-many。希望这会有所帮助。

还将注释从方法移动到字段。这个:

private long id;

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

应该是:

    @Id
    @GeneratedValue
    @Column(name = "CATEGORY_ID")
    private long id;

   public long getId() {
        return id;
    }

多对多关系:

在您的数据库中,您有 3 个表:

  1. 类别
  2. 文章
  3. ARTICLECATEGORYMAP(连接表)

对于多对多关系实体将是:

类别实体:

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

        @Id
        @GeneratedValue
        @Column(name = "CATEGORY_ID")
        private long id;
        private String name;

       @ManyToMany(cascade = { CascadeType.ALL })
       @JoinTable(
        name = "ARTICLECATEGORYMAP", 
        joinColumns = { @JoinColumn(name = "CATEGORY_ID") }, 
        inverseJoinColumns = { @JoinColumn(name = "ARTICLE_ID") }
    )
    Set<Article > articles = new HashSet<>();
     .....
   }

文章实体:

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


    @Id
    @GeneratedValue
    @Column(name = "ARTICLE_ID") 
    private long id;
    private String title;
    private String description;
    private String keywords;
    private String content;

    @ManyToMany(mappedBy = "articles")
    private Set<Category> categories = new HashSet<>();

    .......
    }

欲了解更多信息,请查看many-to-many ralationship

【讨论】:

  • @java 家伙:谢谢你的详细回答,但我必须使用连接表来记住未来,关联可以从“一对多”变为“多对多” .所以我必须使用这个连接表概念。请帮助我,是否可以直接用新值覆盖连接表,或者首先我必须删除第一个关联并创建一个新条目。
猜你喜欢
  • 2011-04-07
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多