3

In a SparePart table the uniqueness of the rows is given from a combination of materialName and materialNumber , what i want to do is get the total number of Spare Parts avalaible now.

I have tried using count(distinct ...) but it only works for one field not two.

The SQL query(using hibernate query language) with an inner query would look like this :

select count(*) from (
     select distinct materialName, materialNo from SparePart
) as col
Sanath
  • 4,774
  • 10
  • 51
  • 81
Viocartman
  • 153
  • 3
  • 14

3 Answers3

4

Use a subquery+group by and then filter for the first ID that represents the particular group, finally count all those that match the filter:

SELECT COUNT(sp2) FROM SparePart sp2 WHERE EXISTS
  (SELECT sp.materialName, sp.materialNo
          FROM SparePart sp
          GROUP BY sp.materialName, sp.materialNo
          HAVING MIN(sp.id)=sp2.id)
Istvan Devai
  • 3,962
  • 23
  • 21
1

You can use hibernate dialect for this task. To do this, create your own dialect, that extends dialect of DB what used (list of all dialects), and then register new function. For example, I use MySQL 5 with InnoDB engine:

public final class MyDialect extends MySQL5InnoDBDialect {
    public MyDialect() {
        super();
        registerFunction("pairCountDistinct", new SQLFunctionTemplate(LongType.INSTANCE, "count(distinct ?1, ?2)"));
    }
}

After then add new property in persistence.xml:

<property name="hibernate.dialect" value="com.example.dialect.MyDialect" />

And now you can use this function:

// some init actions
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteria = builder.createQuery(Long.class);
final Root<SparePart> root = criteria.from(SparePart.class);
criteria.select(builder.function("pairCountDistinct", Long.class, root.get(SparePart_.materialName), root.get(SparePart_.materialNo)));
final long result = entityManager.createQuery(criteria).getSingleResult();
// some close actions
svishevsky
  • 86
  • 1
  • 3
0

You can try it with Criteria API.

ProjectionList projectionList = Projections.projectionList();        
projectionList.add(Projections.property("materialName"));
projectionList.add(Projections.property("materialNo"));

Criteria criteria = session.createCriteria(SparePart.class); 
criteria.setProjection(Projections.distinct(projectionList);  
criteria.setProjection(Projections.rowCount());

Long results = criteria.uniqueResult();

Also, it may need some modifications as I haven't tried it, mapped according to your query.

Nayan Wadekar
  • 11,444
  • 4
  • 50
  • 73