Hibernate创建冗余的多对多表 [英] Hibernate creating redundant many-to-many tables

查看:132
本文介绍了Hibernate创建冗余的多对多表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开发我的Spring Boot应用程序时,我不得不放弃数据库,让Hibernate再次使用 hibernate.hbm2ddl.auto = update 生成它。之后,我想确保它做了我想做的所有事情,所以我打电话给MySQL Workbench对我的整个数据库进行逆向工程。当我这样做时,我注意到由于某种原因,我的模式中有两倍的表。我的表中有很多实体关系,但它们都是一对多的,但由于某种原因,几乎所有的一对多关系都是由Hibernate生成的多对多连接表组成的。这对我来说是一个惊喜,因为这在以前没有发生在同一个Web应用程序中。



通过SO进行的搜索只让我

现在我会提供样本,但我有很多代码,我希望保持简短,所以我将仅切入一个示例。如果您需要查看更多信息,请在您的答案中指定。



例如,我有这个实体:

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

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

//一些属性

@ManyToOne(fetch = FetchType.EAGER,targetEntity = Skill.class)
@JoinColumn(name =PARENT,nullable = true)
@Cascade({CascadeType.DETACH})
//级联注释来自Hibernate,除
//Indexed以外的所有其他元素都来自javax.persistence
private技能父母;

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

// Getters,setters等
}

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



skill_skill image



实际上, 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)
私人长ID;

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

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name =OWNER,nullable = false)
私人用户所有者;
}

我能想到的一些原因:


  1. 摘要 AbstractDomainObject 超类。它只具有受保护的样板功能。尽管如此,它并没有引起任何问题。
  2. 我添加了
  3. @Cascade({CascadeType.DETACH})注释。虽然看起来不太可能。

  4. 我的最后一个变化是我在我的项目中创建了第二个数据源,这就是为什么我改变了我的 @EnableAutoConfiguration @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})。难道现在Hibernate的行为有些不同吗?

  5. 我还将所有实体移动到其他程序包中。

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

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

通过这种方式,Hibernate在维护关系时将忽略一端(并且不会创建连接表这是 @OneToMany 没有 @JoinColumn 的关联的默认配置。)


While developing my Spring Boot application I had to drop my database and have Hibernate generate it again with hibernate.hbm2ddl.auto=update. After that I wanted to make sure it did everything like I wanted to so I called MySQL Workbench to reverse engineer my entire database. When I did that, I noticed that for some reason there were twice as many tables in my schema. I have a lot of entity relationships in my table, but all of them are one-to-many, yet for some reason for almost all of my one-to-many relationships Hibernate has generated many-to-many join tables. It came as a surprise to me because this didn't happen before with the same web application.

My search through SO has only led me to this question which seems irrelevant.

Now I will provide samples, but I have a lots of code and I want to keep it short, so I will cut to only one example. If you need to see more, please specify this in your answer.

So, for instance, I have this entity:

@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
}

You can see that this entity references itself. Skills are a tree here. So, Hibernate interprets this as:

skill_skill image

In fact, skill_skill table isn't even being used. You can see that skill still references itself without this table. When I insert new data in this table, nothing new appears in skill_skill. Although these two entities for some reason don't get extra table:

role and user image

These two object have one-side relationship here:

@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;
}

Some causes I can think on:

  1. Abstract AbstractDomainObject superclass. It only has protected boilerplate functions. It didn't cause any problem before though.
  2. @Cascade({CascadeType.DETACH}) annotation that I added. Although seems unlikely.
  3. My last change was that I created a second data source in my project, this is why I changed my @EnableAutoConfiguration to @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class}). Could it be that Hibernate behaves somehow differently now?
  4. I also moved all my entities causing trouble to a different package.

解决方案

What you have here is a bidirectional association in which both sides are owners, turning it basically to two independent associations. In a one-to-many association the owner is usually the many-to side (note the mappedBy attribute):

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

This way Hibernate will ignore one-to side when maintaining the relationship (and will not create the join table which is the default configuration for @OneToMany association without @JoinColumn).

这篇关于Hibernate创建冗余的多对多表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆