在开发我的Spring Boot应用程序时,我不得不放弃我的数据库并让Hibernate使用hibernate.hbm2ddl.auto = update再次生成它.之后我想确保它完成了我想做的所有事情,所以我打电话给MySQL Workbench来反向工程我的整个数据库.当我这样做时,我注意到由于某种原因,我的架构中有两倍的表.我的表中有很多实体关系,但它们都是一对多的,但由于某种原因,几乎所有的一对多关系Hibernate都生成了多对多的连接表.这让我感到意外,因为之前使用相同的Web应用程序并没有发生这种情况.
我通过搜索引擎优化只搜索了一个似乎无关紧要的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 children;
//Getters, setters, etc
}
您可以看到此实体引用自身.技能在这里是一棵树.所以,Hibernate将其解释为:
事实上,甚至没有使用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;
}
我能想到的一些原因:
> Abstract AbstractDomainObject超类.它只具有保护的样板功能.之前它没有引起任何问题.
>我添加的@Cascade({CascadeType.DETACH})注释.虽然似乎不太可能
>我的最后一个更改是我在项目中创建了第二个数据源,这就是为什么我将@EnableAutoConfiguration更改为@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class}).可能是Hibernate现在表现得有些不同吗?
>我还将所有实体移动到另一个包中.