This is an automated email from the ASF dual-hosted git repository. struberg pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/openjpa.git
commit 9461ffdfcd870b1aeadf1eab3e8181c983a595b4 Author: Mark Struberg <strub...@apache.org> AuthorDate: Wed Oct 31 20:51:31 2018 +0100 OPENJPA-2775 OPENJPA-2555 fraction of seconds in MySQL This is a first fix for supporting fractions of a second in MySQL. --- .../src/main/resources/META-INF/persistence.xml | 3 +- .../org/apache/openjpa/jdbc/meta/MappingInfo.java | 20 +++----- .../org/apache/openjpa/jdbc/sql/DBDictionary.java | 53 ++++++++++++++++++++-- .../apache/openjpa/jdbc/sql/MySQLDictionary.java | 16 +++++-- .../openjpa/persistence/access/FieldSub3.java | 1 + .../persistence/access/TestExplicitAccess.java | 3 ++ openjpa-slice/pom.xml | 2 +- pom.xml | 8 ++-- 8 files changed, 79 insertions(+), 27 deletions(-) diff --git a/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml b/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml index 1f5d266..a561180 100644 --- a/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml +++ b/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml @@ -21,8 +21,7 @@ version="1.0"> <persistence-unit name="jestdemo"> - - <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> + <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <class>demo.Movie</class> <class>demo.Actor</class> diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java index 2af5541..454e4a1 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java @@ -582,17 +582,17 @@ public abstract class MappingInfo implements Serializable { getMappingDefaults().defaultMissingInfo(); if ((!given.isEmpty() || (!adapt && !fill)) && given.size() != tmplates.length) { - // also consider when this info has columns from multiple tables - given = getColumns(table.getIdentifier()); - if ((!adapt && !fill) && given.size() != tmplates.length) { - // try default table - given = getColumns(""); + // also consider when this info has columns from multiple tables + given = getColumns(table.getIdentifier()); + if ((!adapt && !fill) && given.size() != tmplates.length) { + // try default table + given = getColumns(""); if ((!adapt && !fill) && given.size() != tmplates.length) { throw new MetaDataException(_loc.get(prefix + "-num-cols", context, String.valueOf(tmplates.length), String.valueOf(given.size()))); - } - } + } + } } Column[] cols = new Column[tmplates.length]; @@ -607,12 +607,6 @@ public abstract class MappingInfo implements Serializable { return cols; } - boolean canMerge(List<Column> given, Column[] templates, boolean adapt, - boolean fill) { - return !((!given.isEmpty() || (!adapt && !fill)) - && given.size() != templates.length); - } - /** * Set the proper internal column I/O metadata for the given column's flags. */ diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java index 5b09b91..233e184 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java @@ -428,6 +428,24 @@ public class DBDictionary protected final Set<String> systemSchemaSet = new HashSet<>(); protected final Set<String> systemTableSet = new HashSet<>(); protected final Set<String> fixedSizeTypeNameSet = new HashSet<>(); + + /** + * set of types that only accept a single precision... + */ + protected final Set<String> fractionalTypeNameSet = new HashSet<>(); + + /** + * Default amount of digits for fractional Types. + * This is not supported/required by every database. + * + * This value is only being used if no explicit {@code @Column(scale=n)} is set. + * Use {@code @Column(scale=-1)} to disable the scale + * @see #fractionalTypeNameSet + * @see #getFractionLength(Column, String) + */ + protected int defaultFractionLength = 6; + + protected final Set<String> typeModifierSet = new HashSet<>(); // NamingConfiguration properties @@ -1838,15 +1856,32 @@ public class DBDictionary * subclasses. */ protected String appendSize(Column col, String typeName) { - if (fixedSizeTypeNameSet.contains(typeName.toUpperCase(Locale.ENGLISH))) + String upperCaseTypeName = typeName.toUpperCase(Locale.ENGLISH); + if (fixedSizeTypeNameSet.contains(upperCaseTypeName)) { return typeName; - if (typeName.indexOf('(') != -1) + } + if (typeName.indexOf('(') != -1) { return typeName; + } + String size = null; - if (col.getSize() > 0) { + int colSize = col.getSize(); + + if (colSize<=0 && fractionalTypeNameSet.contains(upperCaseTypeName)){ + // special handling for types with fractions + // Attention! We abuse @Column(scale=n) + // One can disable all fractions with @Column(scale=-1) + if (col.getDecimalDigits() != 0) { // the default + colSize = col.getDecimalDigits() == -1 ? 0 : col.getDecimalDigits(); + } + else { + colSize = getFractionLength(col, typeName); + } + size = "(" + colSize + ")"; + } else if (colSize > 0) { StringBuilder buf = new StringBuilder(10); - buf.append("(").append(col.getSize()); + buf.append("(").append(colSize); if (col.getDecimalDigits() > 0) buf.append(", ").append(col.getDecimalDigits()); buf.append(")"); @@ -1857,6 +1892,16 @@ public class DBDictionary } /** + * Only get's used if no explicit scale is used. + * Attention! @{code @Column(scale=-1)} disables the scale of a column + * @return the fraction length of types which have a fraction + * @see #fractionalTypeNameSet + */ + protected int getFractionLength(Column col, String typeName) { + return defaultFractionLength; + } + + /** * Helper method that inserts a size clause for a given SQL type. * * @param typeName The SQL type e.g. INT diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java index 43209f1..580fa8b 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java @@ -75,7 +75,7 @@ public class MySQLDictionary * combined <code>DELETE FROM foo, bar, baz</code> syntax. * Defaults to false, since this may fail in the presence of InnoDB tables * with foreign keys. - * @see http://dev.mysql.com/doc/refman/5.0/en/delete.html + * @link http://dev.mysql.com/doc/refman/5.0/en/delete.html */ public boolean optimizeMultiTableDeletes = false; @@ -99,6 +99,8 @@ public class MySQLDictionary supportsSelectStartIndex = true; supportsSelectEndIndex = true; + + concatenateFunction = "CONCAT({0},{1})"; maxTableNameLength = 64; @@ -195,11 +197,19 @@ public class MySQLDictionary allowsAliasInBulkClause = false; supportsForeignKeysComposite = false; } - if (maj > 5 || (maj == 5 && min >= 1)) + if (maj > 5 || (maj == 5 && min >= 1)) { supportsXMLColumn = true; + } + if (maj > 5 || (maj == 5 && min >= 7)) { + // from this version on MySQL supports fractions of a second + timestampTypeName = "DATETIME{0}"; + fixedSizeTypeNameSet.remove(timestampTypeName); + fractionalTypeNameSet.add(timestampTypeName); + } - if (metaData.getDriverMajorVersion() < 5) + if (metaData.getDriverMajorVersion() < 5) { driverDeserializesBlobs = true; + } } @Override diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java index 8bf91c8..5b8b656 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java @@ -22,6 +22,7 @@ import java.util.Date; import javax.persistence.Access; import javax.persistence.AccessType; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java index 71e1059..f7f87b7 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java @@ -34,6 +34,8 @@ import org.apache.openjpa.persistence.ArgumentException; import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI; import org.apache.openjpa.persistence.test.SingleEMFTestCase; +// -ea -Dopenjpa.ConnectionDriverName=com.mysql.jdbc.Driver -Dopenjpa.ConnectionPassword=openjpatst +// -Dopenjpa.ConnectionURL=jdbc:mysql://localhost:3306/openjpatst -Dopenjpa.ConnectionUserName=openjpatst public class TestExplicitAccess extends SingleEMFTestCase { @Override @@ -476,6 +478,7 @@ public class TestExplicitAccess extends SingleEMFTestCase { fs.setName("EntitySuperName"); // Call base setter with property access Date now = new Date(); + fs.setCreateDate(now); SuperPropertyEntity spe = new SuperPropertyEntity(); diff --git a/openjpa-slice/pom.xml b/openjpa-slice/pom.xml index 4746a0c..74f042b 100644 --- a/openjpa-slice/pom.xml +++ b/openjpa-slice/pom.xml @@ -84,7 +84,7 @@ <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> - <version>${mysql.version}</version> + <version>${mysql.connector.version}</version> <scope>test</scope> </dependency> </dependencies> diff --git a/pom.xml b/pom.xml index 5dbc9d8..c07884e 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ <!-- common JDBC driver versions --> <derby.version>10.14.2.0</derby.version> <hsqldb.version>2.4.1</hsqldb.version> - <mysql.version>8.0.12</mysql.version> + <mysql.connector.version>8.0.13</mysql.connector.version> <postgresql.version>42.2.5</postgresql.version> <!-- other common versions --> <slf4j.version>1.7.23</slf4j.version> @@ -532,7 +532,7 @@ <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> - <version>${mysql.version}</version> + <version>${mysql.connector.version}</version> <scope>test</scope> </dependency> </dependencies> @@ -561,7 +561,7 @@ <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> - <version>${mysql.version}</version> + <version>${mysql.connector.version}</version> <scope>test</scope> </dependency> </dependencies> @@ -1403,7 +1403,7 @@ <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> - <version>${mysql.version}</version> + <version>${mysql.connector.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId>