Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map a property for HQL usage only (in Hibernate)?

i have a table like this one:

id | name | score

mapped to a POJO via XML with Hibernate. The score column i only need in oder by - clauses in HQL. The value for the score column is calculated by an algorithm and updated every 24 hours via SQL batch process (JDBC). So i dont wanna pollute my POJO with properties i dont need at runtime.

For a single column that may be not a problem, but i have several different score columns. Is there a way to map a property for HQL use only?

For example like this:

<property name="score" type="double" ignore="true"/>

so that i still can do this:

from Pojo p order by p.score

but my POJO implementation can look like this:

public class Pojo
{
  private long id;

  private String name;

  // ... 
}

No Setter for score provided or property added to implementation.

using the latest Hibernate version for Java.

Update:

In a perfect world it can be done like this (thanks to Pascal Thivent):

<property name="score" access="noop" insert="false" update="false"/>

But in our real world there exists a bug since years which nobody seems to care about. So does anyone have a suggestions for a workaround?

like image 696
ManBugra Avatar asked Nov 06 '22 13:11

ManBugra


1 Answers

You can use access="noop" in your mapping to specify query-only properties (that's a secret, non documented feature, see HHH-552):

<property name="score" access="noop" insert="false" update="false" ... />

Update: Just to clarify, with the following Entity:

public class EntityWithHqlOnlyProperty implements Serializable {
    private Long id;
    private String name;

    //...
}

And this mapping:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.stackoverflow.q2812672.EntityWithHqlOnlyProperty" table="EntityWithHqlOnlyProperty">
        <id name="id" type="java.lang.Long">
            <column name="id" />
            <generator class="assigned" />
        </id>
        <property name="name" type="string">
            <column name="name" not-null="true" />
        </property>
        <property name="score" type="double" access="noop" insert="false" update="false"/>
    </class>
</hibernate-mapping>

The following snippet:

 Query q = session.createQuery("from EntityWithHqlOnlyProperty e order by e.score");
 List<EntityWithHqlOnlyProperty> resultList = q.list();
 assertNotNull(resultList);

generates the following SQL:

select 
  entitywith0_.id as id6_, 
  entitywith0_.name as name6_, 
  entitywith0_.score as score6_ 
 from 
  EntityWithHqlOnlyProperty entitywith0_ 
 order by
  entitywith0_.score

And in my real world, the test just passes. This has been tested with Hibernate Core 3.3.2.GA on Derby and HSQLDB. In other words, it works on my machine (c).

If it doesn't for you - and I don't mean to be rude but - in a perfect world you should provide a test case allowing to reproduce HHH-2925 as requested for 3+ years. Providing a way to reproduce a problem (I couldn't) highly increases the chances to get it fixed.

like image 125
Pascal Thivent Avatar answered Nov 11 '22 03:11

Pascal Thivent