After I generated my entities and got all the basic functionality of a JHipster application running, I started working on a multi-table join query that I want to use for reporting. I don't want to query individual records and then aggregate my query results into a report using java; this is inefficient, and a single query can do all of the work for me, keeping the database doing what it does best. So I wrote the query, and I then had to figure out how best to use this query in the JHipster framework.
The best option seems to be using JPA's native SQL API and mapping results to a custom data object. I can inject an EntityManager, and that allows me to call createNativeQuery(). I can then call setParameter() for each parameter needed by referencing my parameters by name like this:
Query
select foo
from bar
where some_column = :columnParam
API
nativeQuery.setParameter("columnParam", <valueToUse>)
So far, so good. When I make this call at runtime, however, I get this error:
org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet
...
...
Caused by: java.sql.SQLException: Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '='
Some googling suggests that this is an old/known problem for MySQL, though it is new to me. The problem is that the code and configuration generated by JHipster runs spring boot such that it assumes a collation / character set that supports utf8mb4, which is a more complete utf8 set that can represent emojis, etc. While I have no need for this, I don't want to walk down a backwards road in the learning process.
Fortunately, after searching around a lot, I came to a fairly simple answer: re-create the database (JHipster helped with this by configuring and using liquibase to generate database contents on startup -- hurray!) using the desired collation and character set for the database in MySQL. For me, that ended up being:
Character set: utf8mb4 -- UTF-8 Unicode
Collation: utf8mb4_general_ci
After I made this change, the query started working successfully.
The best option seems to be using JPA's native SQL API and mapping results to a custom data object. I can inject an EntityManager, and that allows me to call createNativeQuery(). I can then call setParameter() for each parameter needed by referencing my parameters by name like this:
Query
select foo
from bar
where some_column = :columnParam
API
nativeQuery.setParameter("columnParam", <valueToUse>)
So far, so good. When I make this call at runtime, however, I get this error:
org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet
...
...
Caused by: java.sql.SQLException: Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '='
Some googling suggests that this is an old/known problem for MySQL, though it is new to me. The problem is that the code and configuration generated by JHipster runs spring boot such that it assumes a collation / character set that supports utf8mb4, which is a more complete utf8 set that can represent emojis, etc. While I have no need for this, I don't want to walk down a backwards road in the learning process.
Fortunately, after searching around a lot, I came to a fairly simple answer: re-create the database (JHipster helped with this by configuring and using liquibase to generate database contents on startup -- hurray!) using the desired collation and character set for the database in MySQL. For me, that ended up being:
Character set: utf8mb4 -- UTF-8 Unicode
Collation: utf8mb4_general_ci
After I made this change, the query started working successfully.
Comments
Post a Comment