我是靠谱客的博主 刻苦板栗,这篇文章主要介绍Hibernate MySQL方言配置遇到的坑,现在分享给大家,希望可以做个参考。

环境 hibernate5.2.17、MySQL5.5,采用JPA注解配置

1. The First

配置文件:peresistence.xml

复制代码
1
2
3
4
5
6
//...其它略... <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="create" />

运行TestApp,报了异常

异常:

复制代码
1
2
3
4
5
2018-09-15 15:46:06 WARN ExceptionHandlerLoggedImpl:27 - GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement ...略.... Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=MyISAM' at line 21

原因:
  MyISAM引擎不支持外键,创建不了表并报错 。
  MySQLDialect是MySQL5.X之前的版本,其默认的引擎是MyISAM。部分源码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
private MySQLStorageEngine storageEngine; //org.hibernate.dialect.MySQLDialect.getDefaultMySQLStorageEngine() protected MySQLStorageEngine getDefaultMySQLStorageEngine() { return MyISAMStorageEngine.INSTANCE; } //org.hibernate.dialect.MyISAMStorageEngine.getTableTypeString(String) @Override public String getTableTypeString(String engineKeyword) { return String.format( " %s=MyISAM", engineKeyword ); }

所以更改配置

复制代码
1
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>

2. The second

  改为上面的配置后,运行,未报异常,表创建成功。

表如下:
这里写图片描述

等等,外键呢 ??!??
 去控制台查看sql

这里写图片描述

  发现存储引擎还是 engine=MyISAM ,于是又去查看 MySQL5Dialect 的源码。

复制代码
1
2
//org.hibernate.dialect.MySQL5Dialect public class MySQL5Dialect extends MySQLDialect{}

  MySQL5Dialect 继承自 MySQLDialect,发现其源码中并没有更改默认存储引擎,
所以然是 MyISAM。但是MySQL5Dialect并没有报异常,能够创建表。

PS:在Navicat中手动添加外键,选择外键的时候有如下提示:

synchronized foreign keys
to
diagram
点击保存外键,然后外键消失。这时候就要注意存储引擎了。

3. The third

改为如下配置:

复制代码
1
2
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL55Dialect"/>

这次OK了。其源码如下,继承自 MySQL5Dialect ,但 以看到改用了InnoDB存储引擎。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//org.hibernate.dialect.MySQL55Dialect public class MySQL55Dialect extends MySQL5Dialect { @Override protected MySQLStorageEngine getDefaultMySQLStorageEngine() { return InnoDBStorageEngine.INSTANCE; } } //org.hibernate.dialect.InnoDBStorageEngine public class InnoDBStorageEngine implements MySQLStorageEngine{ public static final MySQLStorageEngine INSTANCE = new InnoDBStorageEngine(); @Override public String getTableTypeString(String engineKeyword) { return String.format( " %s=InnoDB", engineKeyword ); } }

如下也行。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL57Dialect"/> //MySQL57Dialect继承自MySQL55Dialect,添加了一些新的数据格式。 //org.hibernate.dialect.MySQL57Dialect public class MySQL57Dialect extends MySQL55Dialect {} <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/> // MySQL5InnoDBDialect。已弃用,所以不推荐。 /** A Dialect for MySQL 5 using InnoDB engine * * @author Gavin King, * @author Scott Marlow * @deprecated Use "hibernate.dialect.storage_engine=innodb" environment variable or JVM system property instead. */ @Deprecated public class MySQL5InnoDBDialect extends MySQL5Dialect { @Override protected MySQLStorageEngine getDefaultMySQLStorageEngine() { return InnoDBStorageEngine.INSTANCE; } }

但是使用如下方言,又双叒叕报错了,创建不了表并报错。

复制代码
1
org.hibernate.dialect.MySQLInnoDBDialect

源码如下,继承自MySQLDialect ,又弃用了,但是它设置了InnDB存储引擎 。为什么报错 ???这个坑没爬上来,求指点。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** * A Dialect for MySQL using InnoDB engine * * @author Gavin King * @deprecated Use "hibernate.dialect.storage_engine=innodb" environment variable or JVM system property instead. */ @Deprecated public class MySQLInnoDBDialect extends MySQLDialect { @Override protected MySQLStorageEngine getDefaultMySQLStorageEngine() { return InnoDBStorageEngine.INSTANCE; } }

附:

TestApp

复制代码
1
2
3
4
5
6
7
8
public class TestApp{ @Test public void testDialect(){ EntityManagerFactory entityManagerFactory = HbnUtil.getEntityManager(); } }

Entity

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Entity @Table(name = "Metar") @DynamicInsert public class Metar { @Id @GenericGenerator(name = "uuid", strategy = "uuid") @GeneratedValue(generator = "uuid") private String mid; ....略... @OneToMany(targetEntity = SkyCondition.class, mappedBy = "metar", fetch = FetchType.EAGER,cascade=CascadeType.ALL) private Set<SkyCondition> skyConditionsSet; ....略setter/getter... } @Entity @Table(name = "sky_condition") public class SkyCondition { @Id @GenericGenerator(name = "uuid", strategy = "uuid") @GeneratedValue(generator = "uuid") private String skyId; @ManyToOne(targetEntity = Metar.class, fetch = FetchType.EAGER) @JoinColumn(name = "metar_id",referencedColumnName="mid") private Metar metar; }

参考:
MySQL存储引擎中的MyISAM和InnoDB区别详解

Hibernate的dialect 方言大全

最后

以上就是刻苦板栗最近收集整理的关于Hibernate MySQL方言配置遇到的坑的全部内容,更多相关Hibernate内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部