问题
I need to make an hibernate SQLQuery with db2 and this query is returning me some fields which are calculated and have no relation with any columns in database.
The goal is setting the values of these sum() calculations from SQLQuery on three new transient fields in a Java Object which already existed.
The SQLQuery uses the syntax:
SELECT id as {entityObject.id},
name as {entityObject.name},
order as {entityObject.order},
SUM(CASE
WHEN pv.value_id = 1
AND pv.value=1 THEN 1 ELSE 0 END) AS {entityObject.someCount}
The problem is that Hibernate complains and says to need a column for someCount. It seems not to help declaring the java field as transient or even using the @Transient annotation from javax.persistence at the same time.
If I only declare in the hbm.xml mapping file:
<property name="id" type="java.lang.Integer" column="someColumn" />
<!-- Some more fields here -->
<!-- THE IMPORTANT ONE -->
<property name="someCount" type="java.lang.Integer"/>
Java Object:
public class EntityObject implements Serializable {
private static final long serialVersionUID = 1479579608940145961L;
private Integer id;
private String name;
private Integer order;
// This is the one giving me hell. I've tried with @Transient also
private transient Integer someCount;
public Category() {
}
public Category(final String name, final Integer order) {
this.name = name;
this.order = order;
}
public Integer getOrder() {
return this.order;
}
public void setOrder(final Integer order) {
this.order = order;
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public Integer getSomeCount() {
return someCount;
}
public void setSomeCount(final Integer count) {
this.someCount = count;
}
}
It asks me for a column, and I have tried inserting a fake column and it does not work. The thing is that I want these 'count' fields only to be set from the SQLQuery and to be empty and null when coming from a regular Hibernate Query.
I have looked at the docs and googled, and it seems that you can declare a field transient by only not declaring it at the hibernate mapping file, but then it does not set it on the object with the "as {entityObject.someCount}" even when I have getters/setters declared.
Help please. Thanks very much in advance.
回答1:
1 Create a POJO:
public class SumValue{
private BigInteger myId;
private String myName;
private BigInteger myOrder;
private BigInteger mySum;
....
getters and setters here
....
}
2 Minor changes in your query
SELECT id as "myId",
name as "myName",
order as "myOrder",
SUM(CASE
WHEN pv.value_id = 1
AND pv.value=1 THEN 1 ELSE 0 END) AS "mySum"
3 Execute native sql
List<SumValue> jobStateViewList = (List<SumValue>)getSessionFactory().getCurrentSession()
.createSQLQuery(yourQuery)
.setResultTransformer(
new AliasToBeanResultTransformer(SumValue.class)
).list();
回答2:
The only option available that might do all this directly from the Database without having to issue additional queries is a Hibernate Formula property:
http://wiki.jrapid.com/w/Formula_(attribute_of_property)
<property name="someCount" formula="select count(*) from some_table where table_key = ?"/>
The ? placeholder will be populated automatically with the ID of the current instance.
来源:https://stackoverflow.com/questions/20139488/hibernate-sqlquery-with-transient-properties