Errors when using mixed-case column name in @JoinColumn
Description
Activity
Steve Ebersole October 28, 2015 at 3:26 AM
As part of verifying that this issue affects 5.0, please just set the "Affects version". Leave the "verify-affects-5.0" label and leave the issue in "Awaiting Response" status; these are critical for us to be able to track these verifications and triage them. Thanks.
Steve Ebersole October 27, 2015 at 7:16 PM
This bug report does not indicate that the reported issue affects version 5.x. Versions prior to 5.x are no longer maintained. It would be a great help to the Hibernate team and community for someone to verify that the reported issue still affects version 5.x. If so, please add the 5.x version that you verified with to the list of affected-versions and attach the (preferably SSCCE) test case you used to do the verification to the report; from there the issues will be looked at during our triage meetings.
For details, see http://in.relation.to/2015/10/27/great-jira-cleanup-2015/
Karl M. Davis October 4, 2014 at 1:37 AM
Oh, just realized that this may be a bit more complicated than described above: these errors didn't use to appear. They only started when I went through and started addressing the JPA spec validation "errors" I had in Eclipse. Those included the fact that I had @Entity
classes and fields marked as final
, and that the GameRound.GameRoundPk
@IdClass
on this class needed to be tweaked: one of its fields was incorrectly an int
, rather than a GameSession.GameSessionPk
reference. As part of fixing that, I had to create the GameSession.GameSessionPk
class.
Unfortunately, I have no clue which of those fixes was the trigger for this issue.
Given a class like the following:
@Entity @IdClass(GameRound.GameRoundPk.class) @Table(name = "`GameRounds`") @DynamicUpdate(true) public class GameRound { @Id @JoinColumn(name = "`gameSessionId`") @ManyToOne private GameSession gameSession; @Id @Column(name = "`roundIndex`", nullable = false, updatable = false) private int roundIndex; // ... }
If the
gameSessionId
column in the actual DB matches that mixed casing, I get errors like this:javax.persistence.RollbackException: Error while committing the transaction at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:94) at com.justdavis.karl.rpstourney.service.app.game.GameSessionsDaoImplIT.getGamesForPlayer(GameSessionsDaoImplIT.java:299) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runners.Suite.runChild(Suite.java:127) at org.junit.runners.Suite.runChild(Suite.java:26) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not prepare statement at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:82) ... 34 more Caused by: org.hibernate.exception.SQLGrammarException: could not prepare statement at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:80) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:196) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareStatement(StatementPreparerImpl.java:96) at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.buildBatchStatement(AbstractBatchImpl.java:152) at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.getBatchStatement(AbstractBatchImpl.java:141) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3102) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77) ... 34 more Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: GAMESESSIONID at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source) at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$1.doPrepare(StatementPreparerImpl.java:103) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:186) ... 49 more Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: GAMESESSIONID at org.hsqldb.error.Error.error(Unknown Source) at org.hsqldb.error.Error.error(Unknown Source) at org.hsqldb.ParserDQL.readSimpleColumnName(Unknown Source) at org.hsqldb.ParserDQL.readSimpleColumnNames(Unknown Source) at org.hsqldb.ParserDML.compileInsertStatement(Unknown Source) at org.hsqldb.ParserCommand.compilePart(Unknown Source) at org.hsqldb.ParserCommand.compileStatement(Unknown Source) at org.hsqldb.Session.compileStatement(Unknown Source) at org.hsqldb.StatementManager.compile(Unknown Source) at org.hsqldb.Session.execute(Unknown Source) ... 53 more
That error is from running against an HSQL DB: it's unhappy that the column's name isn't all-uppercase. I get similar errors with Postgres, too, except that it's unhappy that the column's name isn't all-lowercase.
From some debugging, the problem in the code looks to be at
CopyIdentifierComponentSecondPass.doSecondPass(Map):160
(for the 4.3.6 release's source): theColumn
instance created for the SQL statement is built from the already-parsed-and-so-has-no-backticks representation of the metadata column name, rather than the "raw" column name with the backticks from the metadata. Of course, I have no clue where that raw version of the name is actually maintained, so I couldn't tell you how to resolve this. Apologies!I'm using mixed case column names in all of my entities, but this is my only
@JoinColumn
so far. Not seeing problems like this with the rest of my code.