package com.vladmihalcea.hibernate.masterclass.laboratory.inheritance;

import com.vladmihalcea.hibernate.masterclass.laboratory.util.AbstractTest;
import org.junit.Test;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertEquals;

/**
 * InheritanceGroupByTest - Inheritance GroupBy Test
 *
 * @author Vlad Mihalcea
 */
public class InheritanceGroupByTest extends AbstractTest {

    @Override
    protected Class<?>[] entities() {
        return new Class<?>[]{
                FirmUser.class
        };
    }

    @Test
    public void testTree() {
        doInTransaction(session -> {
            session.save(new FirmUser());
            //List<FirmUser> result = session.createQuery("select distinct a from FirmUser a order by a.id").list();
            List<FirmUser> result1 = (List<FirmUser>) session.createQuery("from FirmUser order by id").list();
            List<Object[]> result2 = (List<Object[]>) session.createQuery("select distinct a, a.id from FirmUser a order by id").list();
            assertEquals(1, result1.size());
            assertEquals(1, result2.size());
        });
    }

    @MappedSuperclass
    public static abstract class GenericHierarchicalDictionary {

        public abstract GenericHierarchicalDictionary getParent();

        public abstract Set<? extends GenericHierarchicalDictionary> getChildren();

    }

    @MappedSuperclass
    public static abstract class BaseEntity implements java.io.Serializable {


        private Integer id;

        private Date createdDate = new Date();


        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        @Temporal(TemporalType.TIMESTAMP)
        @Column(name = "CREATED_DATE", nullable = true)
        public Date getCreatedDate() {
            return createdDate;
        }

        public void setCreatedDate(Date createdDate) {
            this.createdDate = createdDate;
        }

    }

    @Entity
    @Table(name = "BASE_USER")
    @Inheritance(strategy = InheritanceType.JOINED)
    @AttributeOverride(name = "id", column = @Column(name = "ID", nullable = false, insertable = false, updatable = false))
    public static abstract class BaseUser extends BaseEntity {


        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
        @SequenceGenerator(name = "seq", sequenceName = "USER_SEQ", allocationSize = 1)
        public Integer getId() {
            return super.getId();
        }

    }

    @Entity(name = "FirmUser")
    @Table(name = "FIRM_USER")
    public static class FirmUser extends BaseUser {

        private String name;

        @Column(name = "name")
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

}

@@ -137,24 +137,55 @@
 stractTest;%0A
+import org.hibernate.Criteria;%0A
 import org.j
@@ -1095,32 +1095,428 @@
 by id%22).list();%0A
+            List%3CFirmUser%3E result3 = (List%3CFirmUser%3E) session.createSQLQuery(%0A                    %22select * %22 +%0A                    %22from FIRM_USER a %22 +%0A                    %22LEFT JOIN BASE_USER b ON a.id = b.id %22 +%0A                    %22order by a.id%22%0A            )%0A            .addEntity(%22a%22, FirmUser.class)%0A            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)%0A            .list();%0A
             asse
@@ -1581,32 +1581,77 @@
 esult2.size());%0A
+            assertEquals(1, result3.size());%0A
         %7D);%0A    

Add native query workaround as well