micronaut-data
micronaut-data copied to clipboard
Query projection not possible for embedded IDs
Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [ ] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
I have a child entity with an embedded ID field called id, containing two integer fields: parentId, number. I need to find the maximum number value for a certain parent ID. So I defined the following query method with a max projection on the ID's number:
int findMaxIdNumberByIdParentId(int parentId);
When compiling this only yields an error message:
Unable to implement Repository method: ChildRepository.findMaxIdNumberByIdParentId(int parentId). Cannot project on non-existent property idNumber
The only workaround at the moment is to build a native query with EntityManager as defining a method with an explicit query also doesn't work because of another bug (reported in #653).
Steps to Reproduce
- Define entity with embedded ID
- Define repository query method with projection on ID field
- compile => error
Expected Behaviour
Projections on embedded ID should work
Actual Behaviour
Compile error
Environment Information
- Operating System: Windows 10
- Micronaut Version: 2.0.0 (data 1.1.1)
- JDK Version: 8
Does int findMaxNumberByParentId(int parentId); work?
No. Sorry, I forgot to mention that one. It was actually my first try but it caused an error too. I have to check this, but as far as I remember it produced a hibernate runtime error that the field could not be found. I'll try tomorrow and provide the exact error message.
My first try was actually findMaxNumberByIdParentId(int) which yields the following exception at runtime:
java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: number of: sample.pkg.Child [SELECT MAX(child_.number) FROM sample.pkg.Child AS child_ WHERE (child_.id.parentId = :p1)]
Your variant findMaxNumbeByParentId fails on both attributes:
java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: number of: sample.pkg.Child [SELECT MAX(child_.number) FROM sample.pkg.Child AS child_ WHERE (childId_.parentId.parentId = :p1)]
The WHERE clause in the first variant is correctly mapped on the embedded ID (child_.id.parentId). I use this in several queries which work without problems. So I think that the bug is that the projection MaxIdNumber is not mapped in the same way as the criteria. Would that be mapped to child_.id.number the query should work.
I just noticed the same problem for deletes. The projection deleteByIdParentId(int) won't compile and the variant deleteByParentId(int)throws an exception at runtime. Is this the same problem or justifies it a separate issue? Or isn't it supported?
probably the same problem
Would this be the same problem if I was trying to project on a joined table/column?
@Entity
data class Product(
@field:Id
@field:GeneratedValue
var id: Long?,
var name: String,
@field:Relation(value = Relation.Kind.MANY_TO_ONE)
@field:MappedProperty("manufacturerId")
var manufacturer: Manufacturer?
)
@Repository
@JdbcRepository(dialect = Dialect.MYSQL)
interface ProductRepository :CrudRepository<Product, Long> {
fun findByManufacturerId(long manufacturerId): Product?
}
Any update on this? I have the same problem with data jdbc.
This seems to be fixed in Micronaut version 3.9.0 when similar issue #1898 was fixed.