We're updating the issue view to help you get more done. 

Parameter binding mismatch on insert when an @ElementCollection @MapKeyColumn uses a declared field of an @Embeddable value

Description

Considering the following mapping involving an @Entity with an @ElementCollection of type Map with @Embeddable as value and a declared column of this @Embeddable as Key:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Entity @Table(name = "parameters") public class Parameter { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; @ElementCollection @MapKeyColumn(name = "value") @CollectionTable(name = "states", joinColumns = @JoinColumn(name = "parameter_id")) protected Map<Integer, State> states; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<Integer, State> getStates() { return states; } public void setStates(Map<Integer, State> states) { this.states = states; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @Embeddable public class State { @Column(insertable = false, updatable = false) private Integer value; private String level; private String description; public Integer getValue() { return value; } public void setValue(Integer value) { this.value = value; } public String getLevel() { return level; } public void setLevel(String level) { this.level = level; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }

When adding a new "State" class to the Map then Flushing, the number of parameters in the SQL insert
statement does not matches the number of bind parameters. There is one extra
parameter set to null value, which makes the underlaying driver to trigger an
exception (see log below). This has been tested with MariaDB and H2.

Here the test code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class App { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("main"); EntityManager entityManager = emf.createEntityManager(); entityManager.getTransaction().begin(); Parameter type = new Parameter(); type.setName("test_type"); entityManager.persist(type); entityManager.flush(); State state = new State(); state.setLevel("OK"); state.setDescription("Some description"); Map<Integer, State> states = new HashMap<>(); states.put(0, state); type.setStates(states); entityManager.flush(); } }

and the output exception :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 2019-Aug-05 17:11:04 PM [main] INFO org.hibernate.Version - HHH000412: Hibernate Core {[WORKING]} 2019-Aug-05 17:11:04 PM [main] INFO org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found 2019-Aug-05 17:11:04 PM [main] INFO org.hibernate.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.0.4.Final} WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter (file:/home/ben/src/hibernate-bug-elementcollection/target/hibernate-test-1.0-SNAPSHOT.jar) to field java.lang.Throwable.cause WARNING: Please consider reporting this to the maintainers of org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 2019-Aug-05 17:11:05 PM [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 2019-Aug-05 17:11:05 PM [main] INFO org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl - HHH000422: Disabling contextual LOB creation as connection was null 2019-Aug-05 17:11:05 PM [main] WARN org.hibernate.orm.connections.pooling - HHH10001002: Using Hibernate built-in connection pool (not for production use!) 2019-Aug-05 17:11:05 PM [main] INFO org.hibernate.orm.connections.pooling - HHH10001005: using driver [org.h2.Driver] at URL [jdbc:h2:mem:test] 2019-Aug-05 17:11:05 PM [main] INFO org.hibernate.orm.connections.pooling - HHH10001001: Connection properties: {user=sa} 2019-Aug-05 17:11:05 PM [main] INFO org.hibernate.orm.connections.pooling - HHH10001003: Autocommit mode: false 2019-Aug-05 17:11:05 PM [main] INFO org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 20 (min=1) 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - drop table parameters if exists 2019-Aug-05 17:11:06 PM [main] INFO org.hibernate.orm.connections.access - HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@6517bc6b] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - drop table states if exists 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - create table parameters (id integer generated by default as identity, name varchar(255), primary key (id)) 2019-Aug-05 17:11:06 PM [main] INFO org.hibernate.orm.connections.access - HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@f3ae18f] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - create table states (parameter_id integer not null, description varchar(255), level varchar(255), value integer not null, primary key (parameter_id, value)) 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - alter table states add constraint FKbkwnbrioejol8i3pl7g06kda0 foreign key (parameter_id) references parameters 2019-Aug-05 17:11:06 PM [main] INFO org.hibernate.tool.schema.internal.SchemaCreatorImpl - HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@7a8316fa' 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - insert into parameters (id, name) values (null, ?) 2019-Aug-05 17:11:06 PM [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [test_type] 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - call identity() 2019-Aug-05 17:11:06 PM [main] DEBUG org.hibernate.SQL - insert into states (parameter_id, value, description, level) values (?, ?, ?, ?) 2019-Aug-05 17:11:06 PM [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] 2019-Aug-05 17:11:06 PM [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [INTEGER] - [0] 2019-Aug-05 17:11:06 PM [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [VARCHAR] - [Some description] 2019-Aug-05 17:11:06 PM [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [OK] 2019-Aug-05 17:11:06 PM [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [5] as [INTEGER] - [null] 2019-Aug-05 17:11:06 PM [main] INFO org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements 2019-Aug-05 17:11:06 PM [main] WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 90008, SQLState: 90008 2019-Aug-05 17:11:06 PM [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Invalid value "5" for parameter "parameterIndex" [90008-197] Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not insert collection: [fr.texsys.hbtest.domain.Parameter.states#1] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1460) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1440) at fr.texsys.hbtest.App.main(App.java:36) Caused by: org.hibernate.exception.GenericJDBCException: could not insert collection: [fr.texsys.hbtest.domain.Parameter.states#1] at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1374) at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:50) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454) ... 2 more Caused by: org.h2.jdbc.JdbcSQLException: Invalid value "5" for parameter "parameterIndex" [90008-197] at org.h2.message.DbException.getJdbcSQLException(DbException.java:357) at org.h2.message.DbException.get(DbException.java:179) at org.h2.message.DbException.getInvalidValueException(DbException.java:240) at org.h2.jdbc.JdbcPreparedStatement.setParameter(JdbcPreparedStatement.java:1560) at org.h2.jdbc.JdbcPreparedStatement.setNull(JdbcPreparedStatement.java:387) at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:61) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275) at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:358) at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:911) at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1334) ... 8 more

Environment

Linux, openjdk version "11.0.4" 2019-07-16, Ubuntu 4.15.0-55-generic, MariaB / H2

Status

Assignee

Unassigned

Reporter

Benjamin Legendre

Fix versions

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Feedback Requested

2019/08/05

Feedback Requested By

Gail Badner

Components

Affects versions

5.3.10
5.3.7

Priority

Major