Cześć
Zaznaczam od razu, że się uczę, więc moja wiedza jest ograniczona :)
Potrzebuję pomocy, bo szczerze skończyły mi się pomysły, a ciężko szukać rozwiązania tego problemu. Podczas próby zrobienia QueryDSL
z widoku bazodanowego wywala mi:
InvalidPathException: Invalid path: 'truckView.tonnage'
, NoViableAltException: unexpected end of subtree
,
QuerySyntaxException: Invalid path: 'truckView.tonnage' [select vehicleView from com.pack.java.project17.common.VehicleView vehicleView where truckView.tonnage = ?100]] with root cause
I niezależnie co chciałbym wyciągnąć zawsze jest to samo - Invalid Path
.
Mam klasę abstrakcyjną Vehicle
. Po niej dwie klasy dziedziczące Truck
i Car
, które dziedziczą po niej tylko id
. Inheritance -> table per class
. W bazie danych są dwie tabele TRUCK
i CAR
i to śmiga.
Zrobiłem widoki bazodanowe, dla truck
i car
<createView viewName="truck_view">
select id,
tonnage,
CAST(tonnage * 0.74 as double) as factor,
from truck
</createView>
<createView viewName="car_view">
select id,
hp,
weight,
CAST(weight * 0.41 as double) as factor,
from car
</createView>
Do widoków są klasy
@Entity
@Immutable
@Getter
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class VehicleView {
@Id
private int id;
}
@Entity
@Table(name = "truck_view")
@Getter
@NoArgsConstructor
public class TruckView extends VehicleView {
private double tonnage;
private double factor;
}
@Entity
@Table(name = "car_view")
@Getter
@NoArgsConstructor
public class CarView extends VehicleView {
private double hp;
private double factor;
}
Do tego oczywiście repo
public interface VehicleViewRepository extends JpaRepository<VehicleView, Integer>, QuerydslPredicateExecutor<VehicleView> {
}
No i to samo w sobie śmiga ładnie jak używam .findAll()
, ale jak chce użyć QueryDSL
to już są jaja.
Controller...
@GetMapping
public ResponseEntity<List<VehicleView>> getAllVehicles(@ModelAttribute SearchVehicleQuery query) {
return ResponseEntity.ok(vehicleViewService.findAllFromView(query));
}
Service...
public List<VehicleView> findAllFromView(SearchVehicleQuery query) {
String vehicleName = query.getType() + "View";
return vehicleViewRepository.findAll(query.getPredicate(), PageRequest.of(0, Integer.MAX_VALUE))
.getContent().stream()
.filter(v -> v.getClass().getSimpleName().equalsIgnoreCase(vehicleName)).collect(Collectors.toList());
}
A to poniżej SearchVehicleQuery
@Getter
public class SearchVehicleQuery {
private String type;
private Double tonnage;
private Double factor;
private Double hp;
private Double factor;
public Predicate getPredicate() {
BooleanBuilder booleanBuilder = new BooleanBuilder();
Optional.OfNullable(type).orElseThrow(InvalidVehicleException::new);
switch (type) {
case "truck":
Optional.ofNullable(tonnage).map(QTruckView.truckView.tonnage::eq).ifPresent(booleanBuilder::and);
Optional.ofNullable(factor).map(QTruckView.truckView.factor::eq).ifPresent(booleanBuilder::and);
break;
case "car":
Optional.ofNullable(hp).map(QCarView.carView.hp::eq).ifPresent(booleanBuilder::and);
Optional.ofNullable(factor).map(QCarView.carView.factor::eq).ifPresent(booleanBuilder::and);
break;
}
return booleanBuilder;
}
Co zrobiłem tutaj źle? Bo nie wiem nawet, gdzie tutaj dokładnie szukać błędu, a na pewno zrobiłem jakiś głupi błąd.
Będę wdzięczny za pomoc!