I have the following model in MySQL:
{quote}import com.vividsolutions.jts.geom.Point;
@Entity @Table(name = "users") public class User { { Integer age; Point location; } } {quote}
Note that `age` is alphabetically before `location`. In Hibernate code, when extracting values from query results, `age` is processed first, then `location`, in alphabetically order.
If `age` is NULL in the database, then regardless of what the value of `location` in the database is, Hibernate **always** returns NULL for `location`. If I give `age` a non-NULL value, then Hibernate returns correct value, i.e. a valid Point, for `location`. After some debugging, I found out that the bug occurs at the following lines of BasicExtractor: {quote} @Override public J extract(ResultSet rs, String name, WrapperOptions options) throws SQLException { { final J value = doExtract( rs, name, options ); final boolean traceEnabled = log.isTraceEnabled(); if ( value == null || rs.wasNull() ) { { ... return null; } } {quote} The variable `value` was extracted correctly from the ResultSet. It's a Point object matching the data of `location` in the database. However, this Point object is discarded and NULL is returned because `rs.wasNull()` is `true`. It turns out, the flag rs.thisRow.wasNull is not set for column `location`. It still has the value of the previous column, i.e. `age`.
So, if `age` is NULL, then `location` will be set to NULL as well, although it has a valid non-NULL value.
The method which extracts the data for the Geometry column is in the class `MySQLGeometryTypeDescriptor` at the following line:
{quote} @Override public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) { { return new BasicExtractor<X>( javaTypeDescriptor, this ) { {
@Override protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { return getJavaDescriptor().wrap( toGeometry( rs.getBytes( name ) ), options ); }{quote}
It doesn't set the flag rs.thisRow.wasNull after extraction, causing this bug. |
|