0

I have a table(MySql) like

(ID(primary-key), Name, rootId)
(2, asdf, 1)
(3, sdf, 1)
(12, tew, 4)
(13, erwq, 4)

Now I want to select distinct root tsg_ids present in database. In this case It should return 1,4.

I tried

List<Entity> entityList = Entity.find(SELECT DISTINCT t.rootId from table t).list().

In debug mode, I see entity list contains ("1", "4"). Entity.find() can only be taken into "Entity" object, but what I am getting from select query is String. So, I was not able to convert the Entity object to String object in this case.

Is there a way to get distinct values of a non-primary column using PanacheEntity?

Davide D'Alto
  • 7,421
  • 2
  • 16
  • 30

1 Answers1

1

I don't know if you are using Panache with Hibernate Reactive or with Hibernate ORM, but, at the moment, if you want to use Panache, you have to use a projection:

@RegisterForReflection
public class EntityRootIdView {
   public final Long rootId;

   public EntityRootIdView(Long rootId){ 
        this.rootId = rootId;
   }
}

// Panache with Hibernate ORM
List<EntityRootIdView> rootIds = Entity
    .find("SELECT DISTINCT t.rootId from Entity t")
    .project(EntityRootIdView.class)
    .list()

// Panache with Hibernate Reactive
Uni<List<EntityRootIdView>> rootIds = Entity
    .find("SELECT DISTINCT t.rootId from Entity t")
    .project(EntityRootIdView.class)
    .list()

Note that this requires at least Quarkus 2.12.0.Final

Alternatively, you can use the Hibernate Reactive session:

Uni<List<Long>> rootIds = Panache.getSession()
    .chain(session -> session
        .createQuery("SELECT DISTINCT t.rootId from Entity t", Long.class)
        .getResultList() )
    );

Or, if you are using Hibernate ORM, the entity manager:

List<Long> rootIds = Panache.getEntityManager()
    .createQuery( "SELECT DISTINCT t.rootId from Entity t", Long.class )
    .getResultList();

Funny enough, I've just created an issue to make this easier.

Davide D'Alto
  • 7,421
  • 2
  • 16
  • 30
  • I have tried @RegisterForReflection class EntityRootIdView { String rootId; public EntityRootIdView(String rootId){ this.rootId = rootId; } } // Panache with Hibernate ORM List rootIds = Entity .find(SELECT DISTINCT t.rootId from Entity t) .project(EntityRootIdView.class) .list() But I'm getting illegalArgumentException and "SELECT". – LateThanNever Oct 27 '22 at 17:49
  • Are you using Quarkus 1.12 + ? – Davide D'Alto Oct 27 '22 at 18:17
  • I've tested it with one of the quickstarts: https://github.com/DavideD/quarkus-quickstarts/commit/f516d840b7b581d2f743dc8f1e72443c58ab9c44 – Davide D'Alto Oct 27 '22 at 18:21
  • I am using 2.4.1. Not sure why it isn't working for me :( – LateThanNever Oct 27 '22 at 18:50
  • What's the full error message? It's possible that's a bug, but it's hard to say without looking at the project. If you can create a test case, I will have a look. You can also create an issue on GitHiub: https://github.com/quarkusio/quarkus/issues – Davide D'Alto Oct 27 '22 at 18:55
  • What I tried: Created @RegisterForReflection RootEntityProjection class. private final String SELECT_ROOT_QUERY = "SELECT DISTINCT t.rootTsgId from TenantHierarchyEntity t"; List entityList = TenantHierarchyEntity.find(SELECT_ROOT_QUERY).project(RootEntityProjection.class).list(); Exception: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: SELECT near line 1, column 80 [SELECT new com.xxx.RootEntityProjection (rootTsgId) SELECT DISTINCT t.rootTsgId from com.xxx.TenantHierarchyEntity t] – LateThanNever Oct 27 '22 at 19:02
  • Sorry, I made a mistake before, this requires at least Quarkus 2.12 (and not 1.12). It's not going to work with Quarkus 2.4 – Davide D'Alto Oct 27 '22 at 19:13
  • Anyway, you can also try the other solution with `Panache.getEntityManger` – Davide D'Alto Oct 27 '22 at 19:14
  • Thank you so much Davide, changing the quarkus version worked. Except that I need to use same table-column name as attribute in class. – LateThanNever Oct 27 '22 at 20:00