diff --git a/build.gradle b/build.gradle index a444754a7e..0057cec2a7 100644 --- a/build.gradle +++ b/build.gradle @@ -141,6 +141,7 @@ subprojects { subProject -> testRuntime( libraries.h2 ) testRuntime( libraries.hsqldb ) testRuntime( libraries.postgresql ) + testRuntime( libraries.mysql ) testRuntime( libraries.woodstox ) // 6.6 gave me some NPE problems from within checkstyle... diff --git a/databases.gradle b/databases.gradle index 972dcbca75..2e4f573f48 100644 --- a/databases.gradle +++ b/databases.gradle @@ -29,6 +29,13 @@ ext { 'jdbc.user' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test', 'jdbc.url' : 'jdbc:postgresql:hibernate_orm_test' + ], + mysql : [ + 'db.dialect' : 'org.hibernate.dialect.MySQL57InnoDBDialect', + 'jdbc.driver': 'com.mysql.jdbc.Driver', + 'jdbc.user' : 'hibernateormtest', + 'jdbc.pass' : 'hibernateormtest', + 'jdbc.url' : 'jdbc:mysql://localhost/hibernate_orm_test' ] ] } diff --git a/hibernate-core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java b/hibernate-core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java index 853894d0b8..aed21ee05b 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java @@ -11,9 +11,11 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import org.hibernate.HibernateException; +import org.hibernate.boot.model.naming.Identifier; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.type.CustomType; @@ -99,9 +101,11 @@ public final class IdentifierGeneratorHelper { return ( (ResultSetIdentifierConsumer) customType.getUserType() ).consumeIdentifier( rs ); } } + ResultSetMetaData resultSetMetaData = null; int columnCount = 1; try { - columnCount = rs.getMetaData().getColumnCount(); + resultSetMetaData = rs.getMetaData(); + columnCount = resultSetMetaData.getColumnCount(); } catch (Exception e) { //Oracle driver will throw NPE @@ -134,32 +138,45 @@ public final class IdentifierGeneratorHelper { } } else { - if ( clazz == Long.class ) { - return rs.getLong( identifier ); + try { + return extractIdentifier( rs, identifier, type, clazz ); } - else if ( clazz == Integer.class ) { - return rs.getInt( identifier ); - } - else if ( clazz == Short.class ) { - return rs.getShort( identifier ); - } - else if ( clazz == String.class ) { - return rs.getString( identifier ); - } - else if ( clazz == BigInteger.class ) { - return rs.getBigDecimal( identifier ).setScale( 0, BigDecimal.ROUND_UNNECESSARY ).toBigInteger(); - } - else if ( clazz == BigDecimal.class ) { - return rs.getBigDecimal( identifier ).setScale( 0, BigDecimal.ROUND_UNNECESSARY ); - } - else { - throw new IdentifierGenerationException( - "unrecognized id type : " + type.getName() + " -> " + clazz.getName() - ); + catch (SQLException e) { + if(Identifier.isQuoted( identifier )) { + return extractIdentifier( rs, Identifier.toIdentifier( identifier).getText(), type, clazz ); + } + throw e; } } } + private static Serializable extractIdentifier(ResultSet rs, String identifier, Type type, Class clazz) + throws SQLException { + if ( clazz == Long.class ) { + return rs.getLong( identifier ); + } + else if ( clazz == Integer.class ) { + return rs.getInt( identifier ); + } + else if ( clazz == Short.class ) { + return rs.getShort( identifier ); + } + else if ( clazz == String.class ) { + return rs.getString( identifier ); + } + else if ( clazz == BigInteger.class ) { + return rs.getBigDecimal( identifier ).setScale( 0, BigDecimal.ROUND_UNNECESSARY ).toBigInteger(); + } + else if ( clazz == BigDecimal.class ) { + return rs.getBigDecimal( identifier ).setScale( 0, BigDecimal.ROUND_UNNECESSARY ); + } + else { + throw new IdentifierGenerationException( + "unrecognized id type : " + type.getName() + " -> " + clazz.getName() + ); + } + } + /** * Wrap the given value in the given Java numeric class. * diff --git a/hibernate-core/src/test/java/org/hibernate/id/QuotedIdentifierTest.java b/hibernate-core/src/test/java/org/hibernate/id/QuotedIdentifierTest.java new file mode 100644 index 0000000000..78cb64dbb0 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/id/QuotedIdentifierTest.java @@ -0,0 +1,73 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.id; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.Session; +import org.hibernate.Transaction; + +import org.hibernate.testing.DialectChecks; +import org.hibernate.testing.RequiresDialectFeature; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +/** + * @author Vlad Mihalcea + */ +@RequiresDialectFeature( value = DialectChecks.SupportsIdentityColumns.class, jiraKey = "HHH-9271") +public class QuotedIdentifierTest extends BaseCoreFunctionalTestCase { + + @Test + public void testDirectIdPropertyAccess() throws Exception { + Session s = openSession(); + Transaction transaction = s.beginTransaction(); + QuotedIdentifier o = new QuotedIdentifier(); + o.timestamp = System.currentTimeMillis(); + o.from = "HHH-9271"; + s.persist( o ); + transaction.commit(); + s.close(); + + s = openSession(); + transaction = s.beginTransaction(); + o = session.get( QuotedIdentifier.class, o.index ); + assertNotNull(o); + transaction.commit(); + s.close(); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + QuotedIdentifier.class + }; + } + + @Entity(name = "QuotedIdentifier") + @Table( name = "`table`") + public static class QuotedIdentifier { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "`index`") + private int index; + + @Column(name = "`timestamp`") + private long timestamp; + + @Column(name = "`from`") + private String from; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/event/entity/MergeListPreAndPostPersistTest.java b/hibernate-core/src/test/java/org/hibernate/test/event/entity/MergeListPreAndPostPersistTest.java index 3528beb63a..7eb579a152 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/event/entity/MergeListPreAndPostPersistTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/event/entity/MergeListPreAndPostPersistTest.java @@ -14,8 +14,6 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; -import org.junit.Test; - import org.hibernate.Session; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; @@ -24,8 +22,10 @@ import org.hibernate.event.spi.PostInsertEventListener; import org.hibernate.event.spi.PreInsertEvent; import org.hibernate.event.spi.PreInsertEventListener; import org.hibernate.persister.entity.EntityPersister; + import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -68,7 +68,7 @@ public class MergeListPreAndPostPersistTest extends BaseCoreFunctionalTestCase { s.close(); } - @Entity + @Entity(name = "Order") private static class Order { @Id public Long id; @@ -100,7 +100,7 @@ public class MergeListPreAndPostPersistTest extends BaseCoreFunctionalTestCase { } } - @Entity + @Entity(name = "Item") private static class Item { @Id public Long id; diff --git a/libraries.gradle b/libraries.gradle index e19168a214..562bb791c7 100644 --- a/libraries.gradle +++ b/libraries.gradle @@ -86,6 +86,7 @@ ext { hsqldb: "org.hsqldb:hsqldb:2.3.2", derby: "org.apache.derby:derby:10.11.1.1", postgresql: 'org.postgresql:postgresql:9.4-1202-jdbc41', + mysql: 'mysql:mysql-connector-java:5.1.38', jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final", xapool: "com.experlog:xapool:1.5.0", mockito: 'org.mockito:mockito-core:1.9.0',