Community
Participate
Working Groups
We currently do not have an H2 database platform. This database is used by some people and they have asked for this support.
Please review the code and feel free to add it in the next release. One think I don't understand is why the strategy in @Generated annotation is ignored. The following is ignored, if the platform supports identity. @GeneratedValue(strategy=GenerationType.SEQUENCE) Identity is used instead. If I disable identity in the platform class (supportsIdentity() returning false), a global sequence is used as expected. Regards, Michael ------------------------------------------------------------------------ public class H2Platform extends HSQLPlatform { private static final long serialVersionUID = -2935483687958482934L; public H2Platform() { super(); setPingSQL("SELECT 1"); setSupportsAutoCommit(true); } @Override public final boolean isHSQL() { return false; } @Override public void printSQLSelectStatement(DatabaseCall call, ExpressionSQLPrinter printer, SQLSelectStatement statement) { super.printSQLSelectStatement(call, printer, statement); ReadQuery query = statement.getQuery(); if(query != null && query.isReadQuery() && !query.isUserDefined() && !query.isCallQuery()) { int firstRow = query.getFirstResult(); int maxRows = query.getMaxRows(); if(maxRows > 0 || firstRow > 0) { printer.printString(" LIMIT "); if(maxRows > 0) { maxRows -= firstRow; } else { // h2 syntax for limit clause requires max value (offset without limit is not possible) maxRows = Integer.MAX_VALUE; } printer.printPrimitive(maxRows); if(firstRow > 0) { printer.printString(" OFFSET "); printer.printPrimitive(firstRow); } call.setIgnoreFirstRowMaxResultsSettings(true); } } } @Override @SuppressWarnings("unchecked") protected Hashtable buildFieldTypes() { Hashtable fieldTypeMapping = super.buildFieldTypes(); fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition("DATE", false)); fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition("TIME", false)); fieldTypeMapping.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMP", false)); return fieldTypeMapping; } @Override public boolean isAlterSequenceObjectSupported() { return true; } @Override public ValueReadQuery buildSelectQueryForSequenceObject(String seqName, Integer size) { return new ValueReadQuery(new StringBuilder(20 + seqName.length()).append("CALL NEXT VALUE FOR ").append(seqName).toString()); } @Override public Writer buildSequenceObjectAlterIncrementWriter(Writer writer, String fullSeqName, int increment) throws IOException { return writer.append("ALTER SEQUENCE ").append(fullSeqName).append(" INCREMENT BY ").append(Integer.toString(increment)); } @Override public Writer buildSequenceObjectCreationWriter(Writer writer, String fullSeqName, int increment, int start) throws IOException { return writer.append("CREATE SEQUENCE IF NOT EXISTS ").append(fullSeqName).append(" START WITH ").append(Integer.toString(start)) .append(" INCREMENT BY ").append(Integer.toString(increment)); } @Override protected Sequence createPlatformDefaultSequence() { return new NativeSequence(); } @Override public boolean supportsIdentity() { return true; } @Override public ValueReadQuery buildSelectQueryForIdentity() { return new ValueReadQuery("CALL IDENTITY()"); } @Override public void printFieldIdentityClause(Writer writer) throws ValidationException { try { writer.append(" IDENTITY"); } catch(IOException e) { throw ValidationException.logIOError(e); } } @Override public boolean supportsForeignKeyConstraints() { return true; } @Override public boolean supportsLocalTempTables() { return true; } @Override public boolean supportsGlobalTempTables() { return true; } @Override protected String getCreateTempTableSqlPrefix() { return "CREATE TEMPORARY TABLE IF NOT EXISTS "; } @Override public boolean supportsNativeSequenceNumbers() { return true; } @Override public boolean supportsStoredFunctions() { return true; } @Override public ValueReadQuery getTimestampQuery() { return new ValueReadQuery("SELECT CURRENT_TIMESTAMP()"); } @Override protected void initializePlatformOperators() { super.initializePlatformOperators(); addOperator(ExpressionOperator.simpleMath(ExpressionOperator.Concat, "||")); } }
Perhaps, code was tested using the Geodata example.
This class looks good. Please tell me if there is a problem, I know the H2 code base quite well. Regards, Thomas
Created attachment 120068 [details] Compiled version of jar - see readme.txt in the jar
Moving to the incubator component and making this platform available through through our Incubation page. (compiled version is availble here and an SVN version will be available soon in our incubator component) See http://wiki.eclipse.org/EclipseLink/Development/Incubation for more info
See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=258347
The current H2Platform doesn't support sequences, only identity, for primary key generation under EclipseLink 1.0.2. Having supportsSequenceObjects() return true fixes the problem. ### Eclipse Workspace Patch 1.0 #P cis Index: H2Platform.java =================================================================== RCS file: H2Platform.java,v retrieving revision 1.1 diff -u -r1.1 H2Platform.java --- H2Platform.java 21 Apr 2009 22:17:50 -0000 1.1 +++ H2Platform.java 24 Apr 2009 21:20:53 -0000 @@ -108,6 +108,10 @@ return new NativeSequence(); } + public boolean supportsSequenceObjects() { + return true; + } + @Override public boolean supportsIdentity() { return true;
Added to extensions incubator: http://wiki.eclipse.org/EclipseLink/Development/Incubator/Extensions/H2Platform
Adding platform to main stream. Ran foundation LRG and JPA LRG, got all tests passing, except one failure in JPA because of a known bug in shared embeddables with sequencing. Made several test fixes and H2 platform fixes.
Created attachment 150137 [details] H2Platform and test/core fixes
SVN main commit: Bug#215079 - H2Platform Passes foundation LRG, JPA LRG using new H2Platform. Changes: - Added H2Platform, with identity, sequencing, pagination, temp table, functions support. - Exclude no_wait tests from H2 as no no_wait support. - Add test browser login support for H2. - Fixed some Oracle specific function expression tests. - Various test fixes for identity sequencing, and query order. - Exclude OrderedList varchar test from H2, as cannot auto convert varchar to number. - Fixed close issue in emulated drivers. - Various test fixes. - Added new "eclipselink.jdbc.sql-cast" persistence property to disable CAST operation in DB2, Derby, Timesten as normally not required (still on by default). - Added row argument to writeParameterMarker. - Moved sequence creation code up, as common for most platforms. - Added ifNull function, as was missing for most platforms. - Removed logging being turned on in some tests. - Resolve :param=:param test on casting platforms by setting query hint. - Fixed weaver test API change.
Would you consider backporting this fix? I cannot yet move to 2.0.
It should be fairly easy to take the source for the new platform and use it in earlier versions of EclipseLink. All you need is to grab the source, compile it against the earlier EclipseLink version and enable it using: http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Session.2C_Target_Database_and_Target_Application_Server You are looking for the eclipselink.target-database target. If there are any issues with the compile it should be pretty easy to help you solve them on the mailing lists.
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink