gpt4 book ai didi

mysql - Hibernate 创建冗余的多对多表

转载 作者:行者123 更新时间:2023-11-29 01:20:36 24 4
gpt4 key购买 nike

在开发我的 Spring Boot 应用程序时,我不得不删除我的数据库并让 Hibernate 使用 hibernate.hbm2ddl.auto=update 再次生成它。之后,我想确保它按照我的意愿执行所有操作,因此我调用 MySQL Workbench 对我的整个数据库进行逆向工程。当我这样做时,我注意到由于某种原因,我的模式中的表数量是原来的两倍。我的表中有很多实体关系,但它们都是一对多的,但出于某种原因,几乎所有的一对多关系,Hibernate 都生成了多对多连接表。这让我感到惊讶,因为以前在同一个 Web 应用程序中不会发生这种情况。

我通过 SO 的搜索只把我带到了 this似乎无关紧要的问题。

现在我将提供示例,但我有很多代码并且我想保持简短,所以我将只截取一个示例。如果您需要查看更多内容,请在您的回答中注明。

例如,我有这个实体:

@SuppressWarnings("serial")
@Entity
@Indexed
@Table(name = "SKILL")
public class Skill extends AbstractDomainObject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private long id;

//Some properties

@ManyToOne(fetch = FetchType.EAGER, targetEntity = Skill.class)
@JoinColumn(name = "PARENT", nullable = true)
@Cascade({CascadeType.DETACH})
//Cascade annotations are from Hibernate, all else except for
//"Indexed" are from javax.persistence
private Skill parent;

@OneToMany(fetch = FetchType.EAGER, targetEntity = Skill.class)
@Cascade({CascadeType.DETACH})
private Set<Skill> children;

//Getters, setters, etc
}

你可以看到这个实体引用了它自己。技能在这里是一棵树。因此,Hibernate 将其解释为:

skill_skill image

事实上,skill_skill 表甚至没有被使用。你可以看到 skill 在没有这个表的情况下仍然引用自己。当我在此表中插入新数据时,skill_skill 中没有出现任何新数据。虽然这两个实体出于某种原因没有得到额外的表:

role and user image

这两个对象在这里有单边关系:

@SuppressWarnings("serial")
@Entity
@Table(name = "ROLE")
public class Role implements DomainObject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private long id;

@Column(name = "ROLENAME", nullable = false, length = 50)
private String rolename;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "OWNER", nullable = false)
private User owner;
}

我能想到的一些原因:

  1. 抽象 AbstractDomainObject 父类(super class)。它只有 protected 样板功能。不过之前并没有造成任何问题。
  2. @Cascade({CascadeType.DETACH}) 我添加的注解。虽然看起来不太可能。
  3. 我的最后一个更改是我在项目中创建了第二个数据源,这就是为什么我将 @EnableAutoConfiguration 更改为 @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class , DataSourceTransactionManagerAutoConfiguration.class})。会不会是 Hibernate 现在的行为有所不同?
  4. 我还将所有造成问题的实体移到了另一个包中。

最佳答案

这里是一个双向关联,双方都是所有者,基本上变成了两个独立的关联。在一对多关联中,所有者通常是多对端(注意 mappedBy 属性):

OneToMany(fetch = FetchType.EAGER, targetEntity = Skill.class, mappedBy = "parent")
@Cascade({CascadeType.DETACH})
private Set<Skill> children;

这样,Hibernate 在维护关系时将忽略一对一(并且不会创建连接表,这是 @OneToMany 关联的默认配置,没有 @JoinColumn ).

关于mysql - Hibernate 创建冗余的多对多表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35989185/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com