When using grails with a domain class hierarchy similar to the following:
abstract class Vehicle { ... } class Car extends Vehicle { ... } class Motorcycle extends Vehicle { ... }
and the service as follows:
class VehicleService { def startRepairing(Car car) { ... } def startRepairing(Motorcycle motorcycle) { ... } }
We often encounter errors in the following:
No method signature: VehicleService.startRepairing () is applicable for Argument types: (Car _ $$ _ javassist_156) values: [Id: 42343, Class: Car]. Possible solutions: startRepairing (Car)
We believe this is happening because we are extracting the Vehicle
instance from the collection, such as static hasMany = [vehicles: Vehicle]
, which forces the proxy to implement the abstract Vehicle
class, but not the concrete class ( Car
, Motorcycle
, etc.) .
We used to remove the argument type from the method as a solution, but we would prefer it - the code is cleaner, method overloading is possible, more friendly IDE ...
One solution that we were thinking about is to use the infamous GrailsHibernateUtil.unwrapIfProxy when the type does not match any other method:
class VehicleService { def startRepairing(Vehicle vehicle) { startRepairing(GrailsHibernateUtil.unwrapIfProxy(vehicle)) } def startRepairing(Car car) { } def startRepairing(Motorcycle motorcycle) { } }
But then the question arises: how can we verify this? When we run the code in development, we very rarely find the javassist problem, and even in production this happens โby accidentโ (or, more precisely, because of conditions that avoid our knowledge :).
Is it possible to force an instance to be a javassist proxy? What would be a good strategy for such problems in general?