Problem z query z zagnieżdżonych encji

0

Witam,
Mam problem ze stworzeniem zagnieżdżonego query w hibernacie. Moje encje wyglądają następująco:

@Getter
@Setter
@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    @Id
    @GeneratedValue(generator = "uuid-generator")
    @GenericGenerator(name = "uuid-generator", strategy = "uuid2")
    @Column(name = "entity_id", unique = true, nullable = false)
    private String entityId;

    @CreationTimestamp
    @Column(name = "entity_create_date", nullable = false)
    private ZonedDateTime entityCreateDate;

    @UpdateTimestamp
    @Column(name = "entity_last_modified_date")
    private ZonedDateTime entityLastModifiedDate;

    @Version
    @Column(name = "entity_version")
    private Long entityVersion;
}
@Data
@Entity
@Table(name = "report_mcodes")
public class MCodesEntity extends BaseEntity {

    @Column(name = "m_code")
    private String mCode;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "localisation_entity_id", referencedColumnName = "entity_id")
    private List<LocalisationEntity> localisations = Lists.newArrayList();
}
@Data
@Entity
@Table(name = "report_localisations")
public class LocalisationEntity extends BaseEntity {

    @Column(name = "localisation")
    private String localisation;

    @Column(name = "count")
    private Integer count;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "packs_entity_id", referencedColumnName = "entity_id")
    private List<PackEntity> packs = Lists.newArrayList();
}
@Data
@Entity
@Table(name = "report_pack")
public class PackEntity extends BaseEntity {

    @Column(name = "packNumber")
    private String packNumber;

    @Column(name = "packType")
    private String packType;

    @Column(name = "lastOperation")
    private String lastOperation;

    @Column(name = "lastOperationDate")
    private String lastOperationDate;
}

A RepositoryImpl wygląda następująco:

    @Override
    @Transactional(propagation = Propagation.MANDATORY, readOnly = true)
    public List<MCodesEntity> find(final UUID traceId, GxpCriteria gxpCriteria) {

            CriteriaQuery<MCodesEntity> query = createQuery(gxpCriteria);

            final List<MCodesEntity> entities = entityManager
                    .createQuery(query)
                    .getResultList();

            return entities;
}
private CriteriaQuery<MCodesEntity> createQuery(final GxpCriteria gxpCriteria) {

final CriteriaBuilder builder = entityManager.getCriteriaBuilder();

final CriteriaQuery<MCodesEntity> query = builder.createQuery(MCodesEntity.class);

final Root<MCodesEntity> queryRoot = query.from(MCodesEntity.class);

query.where(builder.equal(queryRoot.get("mCode"), gxpCriteria.getMCode()));

        return query;
    }

Ale wtedy sortuję tylko po mCode, a potrzebuję sortować po mCode, localization, packType i lastOperationDate. Czy ktoś umie uzyskać takie zapytanie wchodząc w zagnieżdżenia w kolejnych encjach?

4

Napisz SQL, użyj JdbcTemplate albo JOOQ. Serio.

0

Ok, a jak za pomocą selecta w środku przekazać gxpCriteria.getMCode() do porównania? Nie za bardzo wiem jak to zapytanie stworzyć, mógłbyś podać przykład?

0

Poczytaj o PreparedStatement

0

@AggiCh jak masz np. NamedParameterJdbcTemplate to piszesz coś w stylu:

List<ResultObject> results = jdbcTemplate.query("select a,b,c from table where d = :costam",
    Map.of(
            "costam", 12345
    ),
    (row, rowId) ->
            ResultObject.builder()
                    .withA(row.getString("a"))
                    .withB(row.getString("b"))
                    .withC(row.getLong("c"))
                    .build()
);

W jakimś JDBI jest praktycznie identyczna konstrukcja. Jak użyjesz jOOQ albo QueryDSL to zamiast pisania gołego sqla będziesz mieć buildera do query. Wszystkie te opcje dają ci pełną kontrolę nad zapytaniem.

0

Chyba nie chodziło Tobie o sortowanie, a o filtrowanie.

Takie coś skrobnąłem na kolanie, mniej więcej jakoś tak powinno wyglądać:

final Root<MCodesEntity> queryRoot = query.from(MCodesEntity.class);
final Path<LocalisationEntity> localisationsPath = queryRoot.join(queryRoot.get("localisations"));
...
query.where(builder.equal(queryRoot.get("mCode"), gxpCriteria.getMCode()), builder.equal(localisationsPath.get("localisation"), gxpCriteria.getLocalization()));

1 użytkowników online, w tym zalogowanych: 0, gości: 1