samedi 25 avril 2015

Hibernate is using wrong table name for order by expression with three level inheritance


In our project we have different user types presented by different classes. And we have a BaseEntity class as @MappedSuperclass. When we try to use user classes with InheritanceType.JOINED hibernate creates an sql that we think it is wrong.

Base Entity :

@MappedSuperclass
public 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;
}

}

Base User

@Entity
@Table(name = "BASE_USER")
@Inheritance(strategy = InheritanceType.JOINED)
@AttributeOverride(name = "id", column = @Column(name = "ID", nullable = false, insertable = false, updatable = false))
public 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();
}

}

User

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

private String name;

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

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

}

Sample Code

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {
    try {
        sessionFactory = new AnnotationConfiguration()
                .addAnnotatedClass(FirmUser.class)
                .addAnnotatedClass(BaseUser.class)
                .addAnnotatedClass(BaseEntity.class)
                .configure()
                .buildSessionFactory();
    } catch (Throwable ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

public static Session getSession() throws HibernateException {
    return sessionFactory.openSession();
}

public static void main(String[] args) {
    getSession().save(new FirmUser());

    Query query = getSession().createQuery("select distinct a from FirmUser a ORDER BY a.id");
    query.list();

}
}

For this hql

select distinct a from FirmUser a ORDER BY a.id

hibernate creates this sql

select distinct firmuser0_.ID as ID1_0_, firmuser0_1_.CREATED_DATE as CREATED_2_0_, firmuser0_.name as name1_1_ from FIRM_USER firmuser0_ inner join BASE_USER firmuser0_1_ on firmuser0_.ID=firmuser0_1_.ID order by firmuser0_1_.ID

"order by firmuser0_1_.ID" causes

 HSQLDB  : ORDER BY item should be in the SELECT DISTINCT list:

or

 ORACLE : ORA-01791: not a SELECTed expression

But firmuser0_.ID is in select clause and we actually try to order by ID of FirmUser (firmuser0_) not BaseUser (firmuser0_1_)

If we do not use BaseEntity it works as expected.

Why does hibernate use joined class for ordering in case of it also inherits from another class?


Aucun commentaire:

Enregistrer un commentaire