[java] Hibernate Criteria Query to get specific columns

I am using Criteria Query in my code. It always fires select * from ...

Instead I want to neglect one column(field) from my query as that field have large number of data stored in bytes. And that causing performance issue.

Can any one give an idea for that?


Some Update

I added a projection in my query and it created a query like...

select
    this_.TEMPLATE_ID as y0_,
    this_.TEMPLATE_NAME as y1_,
    this_.CREATE_DATE as y2_,
    this_.UPDATE_DATE as y3_,
    this_.STATUS_CODE as y4_,
    this_.USER_ID as y5_,
    this_.UPDATED_BY as y6_,
    this_.CATEGORY_ID as y7_,
    this_.PRACTICE_ID as y8_ 
from
    templates this_ 
inner join
    user user1_ 
        on this_.USER_ID=user1_.USER_ID 
inner join
    template_categories category2_ 
        on this_.CATEGORY_ID=category2_.CATEGORY_ID 
where
    y4_=? 
    and y8_=? 
    and y5_ in (
        ?, ?
    ) 
order by
    y1_ asc limit ?

And now issue is like.. Unknown column 'y4_' in 'where clause' and same error for y8_ , y5_ means for all where close it gave an error.

I modified it to Query like ...

select
    this_.TEMPLATE_ID as y0_,
    this_.TEMPLATE_NAME as y1_,
    this_.CREATE_DATE as y2_,
    this_.UPDATE_DATE as y3_,
    this_.STATUS_CODE as y4_,
    this_.USER_ID as y5_,
    this_.UPDATED_BY as y6_,
    this_.CATEGORY_ID as y7_,
    this_.PRACTICE_ID as y8_ 
from
    templates this_ 
inner join
    user user1_ 
        on this_.USER_ID=user1_.USER_ID 
inner join
    template_categories category2_ 
        on this_.CATEGORY_ID=category2_.CATEGORY_ID 
where
    this_.STATUS_CODE=1
    and this_.PRACTICE_ID=1 
    and this_.USER_ID in (
        1, 2
    ) 
order by
    y1_ asc limit ?

and it worked. But I don't know how to modify it in HQL?

This question is related to java mysql hibernate hibernate-criteria

The answer is


Use Projections to specify which columns you would like to return.

Example

SQL Query

SELECT user.id, user.name FROM user;

Hibernate Alternative

Criteria cr = session.createCriteria(User.class)
    .setProjection(Projections.projectionList()
      .add(Projections.property("id"), "id")
      .add(Projections.property("Name"), "Name"))
    .setResultTransformer(Transformers.aliasToBean(User.class));

  List<User> list = cr.list();

You can use multiselect function for this.

   CriteriaBuilder cb=session.getCriteriaBuilder();
            CriteriaQuery<Object[]> cquery=cb.createQuery(Object[].class);
            Root<Car> root=cquery.from(User.class);
            cquery.multiselect(root.get("id"),root.get("Name"));
            Query<Object[]> q=session.createQuery(cquery);
            List<Object[]> list=q.getResultList();
            System.out.println("id        Name");
            for (Object[] objects : list) {
                System.out.println(objects[0]+"        "+objects[1]);
             }
            

This is supported by hibernate 5. createCriteria is deprecated in further version of hibernate. So you can use criteria builder instead.


You can use JPQL as well as JPA Criteria API for any kind of DTO projection(Mapping only selected columns to a DTO class) . Look at below code snippets showing how to selectively select various columns instead of selecting all columns . These example also show how to select various columns from joining multiple columns . I hope this helps .

JPQL code :

String dtoProjection = "new com.katariasoft.technologies.jpaHibernate.college.data.dto.InstructorDto"
                + "(i.id, i.name, i.fatherName, i.address, id.proofNo, "
                + " v.vehicleNumber, v.vechicleType, s.name, s.fatherName, "
                + " si.name, sv.vehicleNumber , svd.name) ";

        List<InstructorDto> instructors = queryExecutor.fetchListForJpqlQuery(
                "select " + dtoProjection + " from Instructor i " + " join i.idProof id " + " join i.vehicles v "
                        + " join i.students s " + " join s.instructors si " + " join s.vehicles sv "
                        + " join sv.documents svd " + " where i.id > :id and svd.name in (:names) "
                        + " order by i.id , id.proofNo , v.vehicleNumber , si.name , sv.vehicleNumber , svd.name ",
                CollectionUtils.mapOf("id", 2, "names", Arrays.asList("1", "2")), InstructorDto.class);

        if (Objects.nonNull(instructors))
            instructors.forEach(i -> i.setName("Latest Update"));

        DataPrinters.listDataPrinter.accept(instructors);

JPA Criteria API code :

@Test
    public void fetchFullDataWithCriteria() {
        CriteriaBuilder cb = criteriaUtils.criteriaBuilder();
        CriteriaQuery<InstructorDto> cq = cb.createQuery(InstructorDto.class);

        // prepare from expressions
        Root<Instructor> root = cq.from(Instructor.class);
        Join<Instructor, IdProof> insIdProofJoin = root.join(Instructor_.idProof);
        Join<Instructor, Vehicle> insVehicleJoin = root.join(Instructor_.vehicles);
        Join<Instructor, Student> insStudentJoin = root.join(Instructor_.students);
        Join<Student, Instructor> studentInsJoin = insStudentJoin.join(Student_.instructors);
        Join<Student, Vehicle> studentVehicleJoin = insStudentJoin.join(Student_.vehicles);
        Join<Vehicle, Document> vehicleDocumentJoin = studentVehicleJoin.join(Vehicle_.documents);

        // prepare select expressions.
        CompoundSelection<InstructorDto> selection = cb.construct(InstructorDto.class, root.get(Instructor_.id),
                root.get(Instructor_.name), root.get(Instructor_.fatherName), root.get(Instructor_.address),
                insIdProofJoin.get(IdProof_.proofNo), insVehicleJoin.get(Vehicle_.vehicleNumber),
                insVehicleJoin.get(Vehicle_.vechicleType), insStudentJoin.get(Student_.name),
                insStudentJoin.get(Student_.fatherName), studentInsJoin.get(Instructor_.name),
                studentVehicleJoin.get(Vehicle_.vehicleNumber), vehicleDocumentJoin.get(Document_.name));

        // prepare where expressions.
        Predicate instructorIdGreaterThan = cb.greaterThan(root.get(Instructor_.id), 2);
        Predicate documentNameIn = cb.in(vehicleDocumentJoin.get(Document_.name)).value("1").value("2");
        Predicate where = cb.and(instructorIdGreaterThan, documentNameIn);

        // prepare orderBy expressions.
        List<Order> orderBy = Arrays.asList(cb.asc(root.get(Instructor_.id)),
                cb.asc(insIdProofJoin.get(IdProof_.proofNo)), cb.asc(insVehicleJoin.get(Vehicle_.vehicleNumber)),
                cb.asc(studentInsJoin.get(Instructor_.name)), cb.asc(studentVehicleJoin.get(Vehicle_.vehicleNumber)),
                cb.asc(vehicleDocumentJoin.get(Document_.name)));

        // prepare query
        cq.select(selection).where(where).orderBy(orderBy);
        DataPrinters.listDataPrinter.accept(queryExecutor.fetchListForCriteriaQuery(cq));

    }

You can map another entity based on this class (you should use entity-name in order to distinct the two) and the second one will be kind of dto (dont forget that dto has design issues ). you should define the second one as readonly and give it a good name in order to be clear that this is not a regular entity. by the way select only few columns is called projection , so google with it will be easier.

alternative - you can create named query with the list of fields that you need (you put them in the select ) or use criteria with projection


I like this approach because it is simple and clean:

    String getCompaniesIdAndName = " select "
            + " c.id as id, "
            + " c.name as name "
            + " from Company c ";

    @Query(value = getCompaniesWithoutAccount)
    Set<CompanyIdAndName> findAllIdAndName();

    public static interface CompanyIdAndName extends DTO {
        Integer getId();

        String getName();

    }

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to mysql

Implement specialization in ER diagram How to post query parameters with Axios? PHP with MySQL 8.0+ error: The server requested authentication method unknown to the client Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver' phpMyAdmin - Error > Incorrect format parameter? Authentication plugin 'caching_sha2_password' is not supported How to resolve Unable to load authentication plugin 'caching_sha2_password' issue Connection Java-MySql : Public Key Retrieval is not allowed How to grant all privileges to root user in MySQL 8.0 MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client

Examples related to hibernate

Hibernate Error executing DDL via JDBC Statement How does spring.jpa.hibernate.ddl-auto property exactly work in Spring? Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed JPA Hibernate Persistence exception [PersistenceUnit: default] Unable to build Hibernate SessionFactory Disable all Database related auto configuration in Spring Boot Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] HikariCP - connection is not available Hibernate-sequence doesn't exist How to find distinct rows with field in list using JPA and Spring? Spring Data JPA and Exists query

Examples related to hibernate-criteria

org.hibernate.QueryException: could not resolve property: filename Hibernate Criteria Query to get specific columns Hibernate Group by Criteria Object Hibernate Criteria Restrictions AND / OR combination JPA and Hibernate - Criteria vs. JPQL or HQL