在开发Spring Boot应用程序时,我必须删除数据库,然后让Hibernate用再次生成它hibernate.hbm2ddl.auto=update。之后,我想确保它能够按照我的意愿进行所有操作,因此我调用了MySQL Workbench对整个数据库进行反向工程。当我这样做时,我注意到由于某种原因,我的架构中的表数量是原来的两倍。我的表中有很多实体关系,但是它们都是一对多的,但是由于某种原因,几乎所有的一对多关系Hibernate都生成了多对多联接表。令我惊讶的是,这在同一个Web应用程序中从未发生过。
hibernate.hbm2ddl.auto=update
我对SO的搜索仅使我想到了这个似乎无关紧要的问题。
现在,我将提供示例,但是我有很多代码,并且我想使其简短一些,因此,我仅介绍一个示例。如果您需要更多信息,请在答案中指定。
因此,例如,我有这个实体:
@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图片
实际上,skill_skill表甚至没有被使用。您可以看到,skill没有此表仍然引用自身。当我在此表中插入新数据时,中没有新内容出现skill_skill。尽管这两个实体出于某种原因无法获得额外的表格:
skill_skill
skill
角色和用户形象
这两个对象在这里具有单边关系:
@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; }
我可以考虑一些原因:
AbstractDomainObject
@Cascade({CascadeType.DETACH})
@EnableAutoConfiguration
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
您这里拥有的是双向关联,双方都是所有者,因此基本上将其变成了两个独立的关联。在一对多关联中,所有者通常是多对边(请注意mappedBy属性):
mappedBy
OneToMany(fetch = FetchType.EAGER, targetEntity = Skill.class, mappedBy = "parent") @Cascade({CascadeType.DETACH}) private Set<Skill> children;
这样,Hibernate在维护关系时将忽略一对一的关系(并且不会创建@OneToMany联接表,这是不使用的关联的默认配置@JoinColumn)。
@OneToMany
@JoinColumn