HHH-14407 NPE in Column.getSqlTypeCode(Mapping mapping) for column 'hib_sess_id' when using PersistentTableBulkIdStrategy

This commit is contained in:
Nathan Xu 2021-01-14 22:43:56 -05:00 committed by Christian Beikov
parent 602926bf9b
commit 1e5d64cf79
5 changed files with 121 additions and 3 deletions

View File

@ -137,13 +137,13 @@ public abstract class AbstractMultiTableBulkIdStrategyImpl<TT extends IdTableInf
.append( jdbcEnvironment.getQualifiedObjectNameFormatter().format( idTable.getQualifiedTableName(), dialect ) ) .append( jdbcEnvironment.getQualifiedObjectNameFormatter().format( idTable.getQualifiedTableName(), dialect ) )
.append( " (" ); .append( " (" );
Iterator itr = idTable.getColumnIterator(); Iterator<Column> itr = idTable.getColumnIterator();
while ( itr.hasNext() ) { while ( itr.hasNext() ) {
final Column column = (Column) itr.next(); final Column column = itr.next();
buffer.append( column.getQuotedName( dialect ) ).append( ' ' ); buffer.append( column.getQuotedName( dialect ) ).append( ' ' );
buffer.append( column.getSqlType( dialect, metadata ) ); buffer.append( column.getSqlType( dialect, metadata ) );
final int sqlTypeCode = column.getSqlTypeCode( metadata ); final int sqlTypeCode = column.getSqlTypeCode() != null ? column.getSqlTypeCode() : column.getSqlTypeCode( metadata );
final String columnAnnotation = dialect.getCreateTemporaryTableColumnAnnotation( sqlTypeCode ); final String columnAnnotation = dialect.getCreateTemporaryTableColumnAnnotation( sqlTypeCode );
if ( !columnAnnotation.isEmpty() ) { if ( !columnAnnotation.isEmpty() ) {
buffer.append(" ").append( columnAnnotation ); buffer.append(" ").append( columnAnnotation );

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.hql.spi.id.persistent; package org.hibernate.hql.spi.id.persistent;
import java.sql.Types;
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistry;
@ -111,6 +113,7 @@ public class PersistentTableBulkIdStrategy
protected void augmentIdTableDefinition(Table idTable) { protected void augmentIdTableDefinition(Table idTable) {
Column sessionIdColumn = new Column( Helper.SESSION_ID_COLUMN_NAME ); Column sessionIdColumn = new Column( Helper.SESSION_ID_COLUMN_NAME );
sessionIdColumn.setSqlType( "CHAR(36)" ); sessionIdColumn.setSqlType( "CHAR(36)" );
sessionIdColumn.setSqlTypeCode( Types.VARCHAR );
sessionIdColumn.setComment( "Used to hold the Hibernate Session identifier" ); sessionIdColumn.setComment( "Used to hold the Hibernate Session identifier" );
idTable.addColumn( sessionIdColumn ); idTable.addColumn( sessionIdColumn );
} }

View File

@ -0,0 +1,23 @@
/*
* 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.hhh14407;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
/**
* @author Sönke Reimer
*/
@Entity(name="ChildEntity")
class ChildEntity extends ParentEntity {
@Basic
@Column(name="CHILD")
private String ivChild;
}

View File

@ -0,0 +1,34 @@
/*
* 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.hhh14407;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Version;
/**
* @author Sönke Reimer
*/
@Entity(name="ParentEntity")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
class ParentEntity {
@Id
@Column(name = "ID", length = 32)
private String Id;
@Version
@Column(name = "LOCK_VERSION")
private int Lock_Version;
public String getId() {
return Id;
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.hhh14407;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
/**
* @author Nathan Xu
* @author Sönke Reimer
*/
@RequiresDialect( value = H2Dialect.class )
@TestForIssue( jiraKey = "HHH14407" )
public class PersistentTableBulkIdStrategyNPETest extends BaseCoreFunctionalTestCase {
@Override
protected void configure(Configuration configuration) {
configuration.setProperty(
Environment.DIALECT,
PersistentTableBulkIdH2Dialect.class.getName()
);
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ParentEntity.class,
ChildEntity.class
};
}
@Test
public void hhh14407Test() {
// without fix of HHH14407, the test case will trigger exception due to NPE in PersistentTableBulkIdStrategy
}
public static class PersistentTableBulkIdH2Dialect extends H2Dialect {
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new PersistentTableBulkIdStrategy();
}
}
}