Skip to content
Advertisement

Unable to locate appropriate constructor on class [ClassName]

I want to send a sql query by using Spring JPA like :

"SELECT NEW com.blalba.model.service.FamilyMaterialDto "
            + "(ms.id, mi.partNumber, ftc.commodityType, ftc.materialType, ms.grade, ms.thickness, ms.width) "
            + "FROM MaterialInstance mi, FamilyTypeCommodity ftc, MaterialSpecification ms "
            + "WHERE ftc.materialFamily.id = :familyId "
            + "AND (:typeId is null OR ftc.materialType.id = :typeId) "
            + "AND ftc.id = ms.familyTypeCommodity.id "
            + "AND ms.id = mi.materialSpecification.id "
            + "AND mi.materialSpecification.isActive = true"

However, when I remove some fields like “ms.width”, I get the error:

Unable to locate appropriate constructor on class [com.commencis.sova.model.service.FamilyMaterialDto]. Expected arguments are: java.lang.String, java.lang.String, com.commencis.sova.model.entity.material.CommodityType, com.commencis.sova.model.entity.material.MaterialType, com.commencis.sova.model.entity.material.Grade, com.commencis.sova.model.entity.material.Thickness [SELECT NEW com.commencis.sova.model.service.FamilyMaterialDto (ms.id, mi.partNumber, ftc.commodityType, ftc.materialType, ms.grade, ms.thickness) FROM com.commencis.sova.model.entity.material.MaterialSpecification ms, com.commencis.sova.model.entity.material.MaterialInstance mi, com.commencis.sova.model.entity.material.FamilyTypeCommodity ftc WHERE ftc.materialFamily.id = :familyId AND (:typeId is null OR ftc.materialType.id = :typeId) AND mi.materialSpecification.isActive = true AND ms.id = mi.materialSpecification.id AND ftc.id = ms.familyTypeCommodity.id]

I understand that return Object[] cannot be parsed to DTO object. If I write constructor without the parameter – “Width”, it will work properly. However, I want to provide that a query can be sendable without some parameters(sometimes one of them, sometimes five of them) and a result can be parsable with FamilyMaterialDTO.

How can I do? I don’t have to use DTO, if there is another solution for this problem, please recommend.

Advertisement

Answer

I think you can make the query to return a map and you can create a constructor for FamilyMaterialDTO which takes the argument as a map. And based on the keys present in the map you can set the values… For simplicity let me create my own class.

Class foo { String a; Integer b; Boolean c;}

And a sample query

"select new map (a as a, b as b) from Foo f"

Now this query will return a list of maps and the size of the list depends on how many rows the query returns.

Now you can create a constructor like this. Assume the size of list is 1.

foo (List<Map<?,?> list) { Map map = list.get(0);

If(map.containsKey("a")) this.a = map.get("a");

If(map.containsKey("b")) this.b = map.get("b");

If(map.containsKey("c")) this.c = map.get("c"); }

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement