Reputation: 304
I'm working on a function that with a given criteria, returns it's sql, but i getting sql with criteria aliases. So, are there any way to keep the original column names from database, instead of replacing with alias?
The function:
public String getReportSQL(Criteria criteria) {
try {
CriteriaImpl c = (CriteriaImpl) criteria;
SessionImpl s = (SessionImpl)c.getSession();
SessionFactoryImplementor factory = (SessionFactoryImplementor)s.getSessionFactory();
String[] implementors = factory.getImplementors( c.getEntityOrClassName() );
CriteriaLoader loader = new CriteriaLoader((OuterJoinLoadable)factory.getEntityPersister(implementors[0]),
factory, c, implementors[0], s.getLoadQueryInfluencers());
Field f = OuterJoinLoader.class.getDeclaredField("sql");
f.setAccessible(true);
return (String) f.get(loader);
} catch(Exception e){
throw new RuntimeException(e);
}
}
Got:
select this_.CAR_KEY as CAR_11_0_ from DATABASE.CAR this_
Expected:
select CAR_KEY from DATABASE.CAR
Thanks in advance
Upvotes: 4
Views: 1895
Reputation: 13041
In the general case you can not remove alias generated by hibernate.
Imagine that we have the following entity:
@Entity
@Table(name = "TEST_MESSAGE")
public class Message
{
@Id
@Column(name = "MSG_ID")
private Long id;
@Column(name = "MSG_TEXT")
private String text;
@ManyToOne
@JoinColumn(name="MSG_PARENT_ID")
private Message parent;
...
}
and the following criteria query:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = builder.createQuery(Tuple.class);
Root<Message> root = criteria.from(Message.class);
Path<Long> id = root.get("id");
Path<Message> parent = root.get("parent");
criteria.multiselect(id, parent);
criteria.where( builder.equal( root.get("id"), 2) );
List<Tuple> tuples = session.createQuery( criteria ).getResultList();
...
Hibernate will generate the following sql for it:
select
message0_.MSG_ID as col_0_0_,
message0_.MSG_PARENT_ID as col_1_0_,
message1_.MSG_ID as MSG_ID1_0_,
message1_.MSG_PARENT_ID as MSG_PARENT_ID3_0_,
message1_.MSG_TEXT as MSG_TEXT2_0_
from TEST_MESSAGE message0_
inner join TEST_MESSAGE message1_ on message0_.MSG_PARENT_ID = message1_.MSG_ID
where message0_.MSG_ID = 2
As you can see, if we just remove all aliases (message0_
, message1_
, ...) the query will be invalid. This article throws additional light on this question.
Upvotes: 2
Reputation: 1502
The default Java implementation for declared field "sql" is the one you are getting, and I don't think there is an easy way to change it to the way you want it.
My suggestion is to parse the String you are receiving.
return ((String) f.get(loader)).replaceAll("this_.", "").replaceAll("this_", "").replaceAll("( as \\w)\\w+", "")
Result will be:
select CAR_KEY from DATABASE.CAR
Upvotes: 1