HHH-9271 - IdentityGenerator broken with quoted identifiers

This commit is contained in:
Vlad Mihalcea 2016-03-16 16:01:11 +02:00
parent 11c74b4ebb
commit c62c367957
6 changed files with 125 additions and 26 deletions

View File

@ -141,6 +141,7 @@ subprojects { subProject ->
testRuntime( libraries.h2 ) testRuntime( libraries.h2 )
testRuntime( libraries.hsqldb ) testRuntime( libraries.hsqldb )
testRuntime( libraries.postgresql ) testRuntime( libraries.postgresql )
testRuntime( libraries.mysql )
testRuntime( libraries.woodstox ) testRuntime( libraries.woodstox )
// 6.6 gave me some NPE problems from within checkstyle... // 6.6 gave me some NPE problems from within checkstyle...

View File

@ -29,6 +29,13 @@ ext {
'jdbc.user' : 'hibernate_orm_test', 'jdbc.user' : 'hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test', 'jdbc.pass' : 'hibernate_orm_test',
'jdbc.url' : 'jdbc:postgresql: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'
] ]
] ]
} }

View File

@ -11,9 +11,11 @@ import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.type.CustomType; import org.hibernate.type.CustomType;
@ -99,9 +101,11 @@ public final class IdentifierGeneratorHelper {
return ( (ResultSetIdentifierConsumer) customType.getUserType() ).consumeIdentifier( rs ); return ( (ResultSetIdentifierConsumer) customType.getUserType() ).consumeIdentifier( rs );
} }
} }
ResultSetMetaData resultSetMetaData = null;
int columnCount = 1; int columnCount = 1;
try { try {
columnCount = rs.getMetaData().getColumnCount(); resultSetMetaData = rs.getMetaData();
columnCount = resultSetMetaData.getColumnCount();
} }
catch (Exception e) { catch (Exception e) {
//Oracle driver will throw NPE //Oracle driver will throw NPE
@ -134,32 +138,45 @@ public final class IdentifierGeneratorHelper {
} }
} }
else { else {
if ( clazz == Long.class ) { try {
return rs.getLong( identifier ); return extractIdentifier( rs, identifier, type, clazz );
} }
else if ( clazz == Integer.class ) { catch (SQLException e) {
return rs.getInt( identifier ); if(Identifier.isQuoted( identifier )) {
} return extractIdentifier( rs, Identifier.toIdentifier( identifier).getText(), type, clazz );
else if ( clazz == Short.class ) { }
return rs.getShort( identifier ); throw e;
}
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()
);
} }
} }
} }
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. * Wrap the given value in the given Java numeric class.
* *

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}

View File

@ -14,8 +14,6 @@ import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import org.junit.Test;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType; 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.PreInsertEvent;
import org.hibernate.event.spi.PreInsertEventListener; import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -68,7 +68,7 @@ public class MergeListPreAndPostPersistTest extends BaseCoreFunctionalTestCase {
s.close(); s.close();
} }
@Entity @Entity(name = "Order")
private static class Order { private static class Order {
@Id @Id
public Long id; public Long id;
@ -100,7 +100,7 @@ public class MergeListPreAndPostPersistTest extends BaseCoreFunctionalTestCase {
} }
} }
@Entity @Entity(name = "Item")
private static class Item { private static class Item {
@Id @Id
public Long id; public Long id;

View File

@ -86,6 +86,7 @@ ext {
hsqldb: "org.hsqldb:hsqldb:2.3.2", hsqldb: "org.hsqldb:hsqldb:2.3.2",
derby: "org.apache.derby:derby:10.11.1.1", derby: "org.apache.derby:derby:10.11.1.1",
postgresql: 'org.postgresql:postgresql:9.4-1202-jdbc41', 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", jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final",
xapool: "com.experlog:xapool:1.5.0", xapool: "com.experlog:xapool:1.5.0",
mockito: 'org.mockito:mockito-core:1.9.0', mockito: 'org.mockito:mockito-core:1.9.0',