The effect of schema attribute of @javax.persistence.Table has changed between 5.0.1 and 5.0.2

Description

The meaning/effect of the 'schema' attribute on the @javax.persistence.Table has changed between 5.0.1 and 5.0.2.

Our entity classes are annotated with @Table(name='my_table', schema="my_schema") and upto and including Hibernate 5.0.1 this worked whether it was using a MySQL or SQL Server backend. However, since 5.0.2 this now breaks with a table not found exception. If the catalog attribute is used rather than schema then it works again with MySQL. I wouldn't expect a point release of Hibernate to alter the semantics of such a core element of the mapping configuration.

I've had a look through the changelog in Jira for the 5.0.2 and can't see anything relating to this change, so can only assume that this is an inadvertent side effect of another change.

Environment

None

Activity

Show:
Gareth Powell
October 29, 2015, 2:39 PM

This appears to be related to & HHH-10194, but whereas that was concerned with the NameQualifierSupport in HSQLDialect, my issue is with the MySQLDialect.

Stephen Fikes
January 18, 2017, 7:45 PM

MySQL specific treatment of the concept of 'schema' and 'catalog' may be relevant here as discussed in

Gail Badner
January 27, 2017, 10:56 AM

I am not able to reproduce any inconsistency using MySQL 5.7, mysql-connector-java-5.1.36-bin.jar with 5.0.1, 5.0.2, or 5.0.12.

If schema is set using:

  • @Table( schema="myschema", ...), the schema value is ignored;

  • <property name="hibernate.default_schema" value="myschema"/>, the default schema name is ignored.

If the catalog is set using:

  • @Table( catalog="mycatalog", ...), the table name is prefixed with "mycatalog"

  • <property name="hibernate.default_catalog" value="mycatalog"/>, the table name is prefixed with "mycatalog"

In 5.0.1 and 5.0.12:

  • Hibernate determines that MySQL does not support schemas because DatabaseMetaData#supportsSchemasInTableDefinitions returns false;

  • Hibernate determines that MySQL supports catalogs because DatabaseMetaData#supportsCatalogsInTableDefinitions returns false;

If you are seeing a difference, the please provide a test case that reproduces the difference. Also please provide the exact MySQL version, JDBC version used. You can find test templates at: https://github.com/hibernate/hibernate-test-case-templates

Stephen Fikes
January 30, 2017, 7:46 PM
Edited

See attached test.zip run using MySQL Ver 5.7.17 for Linux on x86_64. The SQL for a query differs when comparing 5.0.1.Final and 5.0.2.Final with only default_schema set.

See README for required configuration. Run using 'mvn test'.

Chris Cranford
February 5, 2017, 2:46 AM

This is due to the change in HHH-10133.

In 5.0.1, we determined the table name by calling into org.hibernate.mapping.Table#getQualifiedName(Dialect,String,String). This method was supplied with both the values defined by the hibernate.default_schema and hibernate.default_catalog properties and internally it prioritized the values from the @Table annotation unless they were not supplied and then it used the default property values. This method then delegated to #qualify(String,String,String) which basically then appended the three supplied strings with catalog first if not null, schema next if not null, and finally the qualified table name.

The problem was that the use of schema and catalog were inconsistent. Had I provided a connection url that used database1 and a hibernate.default_schema that specified database2, the schema generation would create all my objects in database1 but querying entities would use database2. Had I even specified the schema as database2 in the @Table annotation, the schema generation process would have still placed that object in database1. This creates lots of failures, inconsistently behavior, and confusion on the user.

With 5.0.2, we standardized the notion of schema and catalog by aligning which attribute was applicable based on the dialect in use.

So for MySQL, that means if you are using schema, such as hibernate.default_schema property or an attribute on the @Table annotation, it would have absolutely no effect on the object's name because that dialect doesn't support the concept of a schema. Changing those references to use catalog instead would generate the right object names consistently. Respectively, if a dialect supports only catalogs and a user uses schema, they'd experience the same problem and would need to make adjustments.

I understand this change in functionality occurred in a point release of Hibernate, but the functionality as it existed in 5.0.1 was inconsistent and incorrect.

Assignee

Unassigned

Reporter

Gareth Powell

Fix versions

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure