Table 休眠升级后丢失
Table missing after hibernate upgrade
我们刚刚从 WildFly 9 升级到 10,因此也从 Hibernate 4 升级到 5。
我们的应用程序使用派生自具有生成的 id 字段的抽象超级实体的实体。
超级 class 看起来像这样:
@MappedSuperclass
@Access(AccessType.FIELD)
@SqlResultSetMapping(name = EntityId.rsmId,
columns = { @ColumnResult(name = "id", type = Long.class) })
public abstract class EntityId
{
@GeneratedValue(strategy = GenerationType.TABLE, generator = "generator1")
@TableGenerator(name = "generator1",
pkColumnValue = "g1",
initialValue = 0, allocationSize = 1000,
schema = "schema2", table = "sysidgenerator", // MySQL
pkColumnName = "gen_key", valueColumnName = "gen_val")
@Column(name = "id")
@Id
private Long id;
[...]
}
and our datasource is configured like this:
<xa-datasource jndi-name="java:jboss/datasources/MTDS" pool-name="MTDS" enabled="true" use-ccm="false">
<xa-datasource-property name="URL">
jdbc:mysql://server:3306/schema
</xa-datasource-property>
<driver>com.mysql</driver>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<xa-pool>
<min-pool-size>3</min-pool-size>
<max-pool-size>40</max-pool-size>
<is-same-rm-override>false</is-same-rm-override>
<interleaving>false</interleaving>
<pad-xid>false</pad-xid>
<wrap-xa-resource>false</wrap-xa-resource>
</xa-pool>
<security>
<user-name>user</user-name>
<password>password</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
<validate-on-match>false</validate-on-match>
<background-validation>true</background-validation>
<background-validation-millis>15000</background-validation-millis>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
</validation>
<statement>
<prepared-statement-cache-size>0</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</xa-datasource>
有了 Hibernate 4,一切都完美无缺。升级后我们得到以下错误:
ERROR [x.y.z] (default task-13) Caught exception.: javax.ejb.EJBTransactionRolledbackException: org.hibernate.HibernateException: Could not apply work
Caused by: org.hibernate.HibernateException: Unable to perform isolated work
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWork(JtaIsolationDelegate.java:139)
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWorkInNewTransaction(JtaIsolationDelegate.java:100)
... 253 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'schema.sysidgenerator' doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2838)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2212)
at com.mysql.jdbc.jdbc2.optional.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:844)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:504)
at org.hibernate.id.enhanced.TableGenerator.executeQuery(TableGenerator.java:639)
at org.hibernate.id.enhanced.TableGenerator.access0(TableGenerator.java:127)
at org.hibernate.id.enhanced.TableGenerator.execute(TableGenerator.java:541)
at org.hibernate.id.enhanced.TableGenerator.execute(TableGenerator.java:531)
at org.hibernate.jdbc.WorkExecutor.executeReturningWork(WorkExecutor.java:55)
at org.hibernate.jdbc.AbstractReturningWork.accept(AbstractReturningWork.java:34)
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWork(JtaIsolationDelegate.java:133)
... 254 more
出于某种原因,Hibernate 现在正在寻找 table 'schema.sysidgenerator' 而不是像在 @TableGenerator 中配置的那样寻找 'schema2.sysidgenerator'。
我们需要做什么来解决这个问题?
赞赏建议。
此致
您应该尝试 "catalog" 而不是 "schema",因为 MySQL 不支持架构。
有关详细信息,请查看 HHH-9714:
MySQL/MariaDB do not support schemas, they support catalogs. I know it is confusing because the command line lets you say CREATE SCHEMA, but their docs are very clear that this is just a "synonym" for CREATE DATABASE. And the JDBC driver only supports catalogs. In fact their DatabaseMetaData returns false for all {{#supportsSchemasIn?} methods, and true for {{#supportsCatalogsIn?).
This may have been a change from older versions of Hibernate. TBH our support for catalogs and schemas (especially in schema tooling) had been dubious.
我们刚刚从 WildFly 9 升级到 10,因此也从 Hibernate 4 升级到 5。 我们的应用程序使用派生自具有生成的 id 字段的抽象超级实体的实体。 超级 class 看起来像这样:
@MappedSuperclass
@Access(AccessType.FIELD)
@SqlResultSetMapping(name = EntityId.rsmId,
columns = { @ColumnResult(name = "id", type = Long.class) })
public abstract class EntityId
{
@GeneratedValue(strategy = GenerationType.TABLE, generator = "generator1")
@TableGenerator(name = "generator1",
pkColumnValue = "g1",
initialValue = 0, allocationSize = 1000,
schema = "schema2", table = "sysidgenerator", // MySQL
pkColumnName = "gen_key", valueColumnName = "gen_val")
@Column(name = "id")
@Id
private Long id;
[...]
}
and our datasource is configured like this:
<xa-datasource jndi-name="java:jboss/datasources/MTDS" pool-name="MTDS" enabled="true" use-ccm="false">
<xa-datasource-property name="URL">
jdbc:mysql://server:3306/schema
</xa-datasource-property>
<driver>com.mysql</driver>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<xa-pool>
<min-pool-size>3</min-pool-size>
<max-pool-size>40</max-pool-size>
<is-same-rm-override>false</is-same-rm-override>
<interleaving>false</interleaving>
<pad-xid>false</pad-xid>
<wrap-xa-resource>false</wrap-xa-resource>
</xa-pool>
<security>
<user-name>user</user-name>
<password>password</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
<validate-on-match>false</validate-on-match>
<background-validation>true</background-validation>
<background-validation-millis>15000</background-validation-millis>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
</validation>
<statement>
<prepared-statement-cache-size>0</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</xa-datasource>
有了 Hibernate 4,一切都完美无缺。升级后我们得到以下错误:
ERROR [x.y.z] (default task-13) Caught exception.: javax.ejb.EJBTransactionRolledbackException: org.hibernate.HibernateException: Could not apply work
Caused by: org.hibernate.HibernateException: Unable to perform isolated work
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWork(JtaIsolationDelegate.java:139)
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWorkInNewTransaction(JtaIsolationDelegate.java:100)
... 253 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'schema.sysidgenerator' doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2838)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2212)
at com.mysql.jdbc.jdbc2.optional.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:844)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:504)
at org.hibernate.id.enhanced.TableGenerator.executeQuery(TableGenerator.java:639)
at org.hibernate.id.enhanced.TableGenerator.access0(TableGenerator.java:127)
at org.hibernate.id.enhanced.TableGenerator.execute(TableGenerator.java:541)
at org.hibernate.id.enhanced.TableGenerator.execute(TableGenerator.java:531)
at org.hibernate.jdbc.WorkExecutor.executeReturningWork(WorkExecutor.java:55)
at org.hibernate.jdbc.AbstractReturningWork.accept(AbstractReturningWork.java:34)
at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWork(JtaIsolationDelegate.java:133)
... 254 more
出于某种原因,Hibernate 现在正在寻找 table 'schema.sysidgenerator' 而不是像在 @TableGenerator 中配置的那样寻找 'schema2.sysidgenerator'。
我们需要做什么来解决这个问题? 赞赏建议。
此致
您应该尝试 "catalog" 而不是 "schema",因为 MySQL 不支持架构。
有关详细信息,请查看 HHH-9714:
MySQL/MariaDB do not support schemas, they support catalogs. I know it is confusing because the command line lets you say CREATE SCHEMA, but their docs are very clear that this is just a "synonym" for CREATE DATABASE. And the JDBC driver only supports catalogs. In fact their DatabaseMetaData returns false for all {{#supportsSchemasIn?} methods, and true for {{#supportsCatalogsIn?).
This may have been a change from older versions of Hibernate. TBH our support for catalogs and schemas (especially in schema tooling) had been dubious.