ebean: querying by `@Convert`ed properties doesn't seem to work
I have an @Entity with a property of our domain Address type that should be serialized to string when written to db and deserialized when read from it. I tried to use the @Converter and @Convert annotations along with a custom-defined converter (tried both javax.persistence.AttributeConverter and io.ebean.config.ScalarTypeConverter), but when I try to run a query with a where condition for this field, I get the “class cz.sentica.qwazar.domain.Address cannot be cast to class io.ebean.bean.EntityBean” error from findList()
Expected behavior
I think the query builder should run the object given to it through the domain-to-db mapping method (convertToDatabaseColumn for AttributeConverter, unwrapValue for ScalarTypeConverter) and use that in the sql.
Actual behavior
ebean tries to cast the domain object into EntityBean in io.ebeaninternal.server.expression.SimpleExpression.addBindValues and (obviously) fails.
Steps to reproduce
// the converters
@Converter
class AddressConverter : AttributeConverter<Address, String> {
override fun convertToDatabaseColumn(attribute: Address): String = attribute.serialize()
override fun convertToEntityAttribute(dbData: String): Address = Address.parse(dbData)
}
// OR
@Converter
class AddressConverter : ScalarTypeConverter<Address, String> {
override fun getNullValue(): Address = NULL_ADDRESS
override fun unwrapValue(beanType: Address?) = (beanType ?: nullValue).serialize()
override fun wrapValue(scalarType: String?) = scalarType?.let { Address.parse(it) } ?: nullValue
}
// the entity
@Entity
class DatabaseAuditTrace(
@Id
override var gid: String = "",
@Convert(converter = AddressConverter::class)
override var resource: Address = NULL_ADDRESS,
}
// the query
QDatabaseAuditTrace(database).where().resource.equalTo(address).findList()
class cz.sentica.qwazar.domain.Address cannot be cast to class io.ebean.bean.EntityBean (cz.sentica.qwazar.domain.Address and io.ebean.bean.EntityBean are in unnamed module of loader 'app')
java.lang.ClassCastException: class cz.sentica.qwazar.domain.Address cannot be cast to class io.ebean.bean.EntityBean (cz.sentica.qwazar.domain.Address and io.ebean.bean.EntityBean are in unnamed module of loader 'app')
at io.ebeaninternal.server.expression.SimpleExpression.addBindValues(SimpleExpression.java:76)
at io.ebeaninternal.server.expression.DefaultExpressionList.addBindValues(DefaultExpressionList.java:640)
at io.ebeaninternal.server.expression.DefaultExpressionRequest.<init>(DefaultExpressionRequest.java:37)
at io.ebeaninternal.server.query.CQueryPredicates.prepare(CQueryPredicates.java:195)
at io.ebeaninternal.server.query.CQueryBuilder.buildQuery(CQueryBuilder.java:332)
at io.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:338)
at io.ebeaninternal.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:123)
at io.ebeaninternal.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:406)
at io.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1410)
at io.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1389)
at io.ebeaninternal.server.querydefn.DefaultOrmQuery.findList(DefaultOrmQuery.java:1485)
at io.ebean.typequery.TQRootBean.findList(TQRootBean.java:1641)
at cz.sentica.qwazar.auditing.repositories.DatabaseTraceRepository.findAllByResource(DatabaseTraceRepository.kt:55)
at cz.sentica.qwazar.auditing.services.DatabaseAuditService.makeTrace(DatabaseAuditService.kt:53)
Is there some additional step I need to do to be able to use the domain object in a query, or is this an unexpected behavior?
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 20 (10 by maintainers)
ok, I’ve moved the relevant code to a testing repo and wrote a test for the reported behavior, but it works correctly in the testing repository. I’ve also updated ebean in the mean time, so I guess there are two possibilities here - either the ebean upgrade fixed the issue, or it’s something specific to our project’s setup. I’ll try this in our project with updated ebean and if it still fails there, I’ll try to isolate the problem there. thanks for your patience.