Map query results to property - java

Is there way to set results of a query to java DTO property using hibernate ?
Something like,
<hibernate-mapping>
<class name="myDTO" table="my_table">
<property name="myProperty" query="what_i_need" />
</class>
<query name="what_i_need">
<![CDATA[
from .....
]]>
</query>
</hibernate-mapping>
I'm using spring, hibernate, java.

If I understand you correctly #josef-prochazka 's suggestion of using a formula would be what you need.
See also:
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html#mapping-column
http://www.onjava.com/pub/a/onjava/2005/08/03/hibernate.html?page=2
http://www.java2s.com/Code/Java/Hibernate/ColumnFormulaStringConcatenate.htm

Related

Hibernate Named query not know error

I dont know why but when I import this project to Eclipse. This work well.
So, I think this is problem of eclipse project when import to InteliJ IDEA
This not easy such my imagine.
I have class Setting and Setting.hbm.xml for mapping hibernate.
In this class:
<hibernate-mapping>
<class name="Setting" table="setting" lazy="false">
<id name="id" column="id" type="integer">
<generator class="increment" />
</id>
.....
</class>
<query name="select.setting">
from Setting as s where s.id = ? order by s.name
</query>
Now, when I call function
this.getHibernateTemplate().findByNamedQuery("select.setting", params);
This return error
org.springframework.orm.hibernate4.HibernateSystemException: Named query not known: select.setting; nested exception is org.hibernate.MappingException: Named query not known: select.setting
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:218) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:343) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.orm.hibernate4.HibernateTemplate.findByNamedQuery(HibernateTemplate.java:933) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
Please give advice about it.
You can give a try with this.
<query name="select.setting">
<![CDATA[from Setting as s where s.id = ? order by s.name]]>
</query>
The XML parser gets confused of you are not using CDATA tag.
CDATA is way of telling the framework that its a data which should not be interpreted as a markup.
Hence as #Lovababu mentioned, include the query inside CDATA tags:
<query name="select.setting">
<![CDATA[from Setting as s where s.id = ? order by s.name]]>

Flexible Hibernate Named Query Mapping

I'm using multiple hibernate named queries that maps to the same hibernate class.
The problem is because the different named queries return different attributes, and not all the attributes I'm getting an "invalid column" error. The way to resolve it is to make sure the queries map all the attributes defined by the hibernate class. (Hibernate native query : Invalid Column Name Error SQL-17006)
Here's an sample of what I have:
<hibernate-mapping>
<class name="com.company.ObjectA" mutable="false" >
<id name="id" type="string"/>
<property name="prop1" type="string"/>
<property name="prop2" type="string"/>
</class>
<sql-query name="get1">
<return alias="a" class="com.company.ObjectA"/>
<![CDATA[
select
id as {a.id},
prop1 as {a.prop1}
from TABLE_A
]]>
</sql-query>
<sql-query name="get2">
<return alias="a" class="com.company.ObjectA"/>
<![CDATA[
select
id as {a.id},
prop2 as {a.prop2}
from TABLE_A
]]>
</sql-query>
</hibernate-mapping>
I have defined a temporary fix where the queries return empty values to make sure all hibernate class attributes are mapped:
<sql-query name="get2">
<return alias="a" class="com.company.ObjectA"/>
<![CDATA[
select
id as {a.id},
'' as {a.prop1},
prop2 as {a.prop2}
from TABLE_A
]]>
</sql-query>
But that is not ideal, because for my real case, I have quite a few of these unmapped attributes, and more named queries that use a different combination of attributes in the hibernate class.
Is there another way to resolve it? Also I need it to return data to the same object 'ObjectA', because of it's integration with the rest of the code.

How to map a HashMap with a List as a value in Hibernate

As the subject says I want to map a HashMap with a List as a value in Hibernate.
Since it looks like it is not possible to have a collection as element in a map in Hibernate, I have created a class that contains a list of Ids.
My HashMap looks like this:
Map<Status, IdList> statusIdsMap = new HashMap<Status, IdList>();
Status is either insert/update/remove. IdList contains a List of Ids.
Hibernate mapping looks like this:
<id name="id" type="IdType" />
...
<map name="statusIdMap">
<key column="id" />
<map-key type="Status" column="StatusCode" />
<element type="IdList" />
</map>
...
<class name="IdList" select-before-update="true" table="IdList">
<id name="id" column="id" unsaved-value="null">
<generator class="IdGenerator"/>
</id>
<set name="Ids" table="IdsForStatus">
<key column="id"/>
<element column="updatedId" type="IdType"/>
</set>
</class>
If I try to store the class with statusIdMap, Hibernate generates an Insert SQL that tries to put the IdList class in a column, instead of the Id to the IdList class.
The Hibernate error message says "expected number, got binary".
It's related question to this
Hibernate(JPA) mapping a HashMap
where the answer suggests to put list in the Key class, but it's not something I wish to do.
Any other suggestions?
EDIT:
In short the test does following:
Fills object with dummy values, including map.
Initializing hibernate and starts a transaction
Inserts object
Commits transaction and closes hibernate session
The error message comes from the database when trying to commit, since the generated insert statement is wrong as mentioned above.

How do I avoid the query calling associated objects

I am sure there is a hibernate term for this but I am not sure what it is (and I could therefore probably look up the answer) but here goes.
I have a Product Pojo where one of the fields is a Set of Suppliers (also a Pojo). When I call to get a list of Products, by default it queries to get the list of Suppliers- which is what I would expect.
However, sometimes I do not require the data in the Set and the querying it is taking too long to just bear it. Is there a way to sometimes avoid querying the data for the Set?
Or is my design incorrect?
My Product.hbm.xml mapping file has:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field" default-lazy="false" package="model">
<class name="model.Product" table="PRODUCT">
<id column="PRODUCT_ID" name="id" type="long">
<generator class="native" />
</id>
...
<set name="suppliers" sort="unsorted" table="SUPPLIERS">
<key column="PRODUCT_ID" />
<one-to-many class="model.Suppliers" />
</set>
...
</class>
</hibernate-mapping>
The default behavior of Hibernate is what you are expecting: All collections mapped for an entity, and all associated entities, be it through to-many or to-one associations, are not loaded by default.
But if you have defined the lazy="false" for the Set of Suppliers, Hibernate will fetch the associated collection eagerly along with the Product.
Change the suppliers mapping as below, so that Hibernate will not fetch it eagerly:
<set name="suppliers" sort="unsorted" table="SUPPLIERS" lazy="true">
<key column="PRODUCT_ID" />
<one-to-many class="model.Suppliers" />
</set>
EDIT:
The above mapping is the default fetching strategy for suppliers. Now if you want to load suppliers along with the Product, you can override this default strategy at runtime in code:
String productSelect = "select p from Product "
+ "p left join fetch p.suppliers "
+ "where p.productName=:pname";
Query query = session.createQuery(productSelect);
query.setParameter("pname", productname);
Product result = (Product) query.uniqueResult();
The above query will fetch the Product along with the set of suppliers. So, wherever needed, you can override the default strategy by using above query to get suppliers along with Product.
Set the fetchtype to LAZY (instead of EAGER) for the supplier Set.

Not null key while doing insert using hibernate

I am new to Hibernate and was writing some test program.
I am wondering if its a must to have a table , one column of which will be updated using some kind of sequence.
For ex. I created a table
create table course(course_name varchar2(20));
and when I am defining Course.hbm.xml in the following way
<class name="Course" table="COURSE" >
<property name="course">
<column name="course"/>
</property>
</class>
I am getting an error in the XML file saying a declaration of "id" or something similar is expected. I can give the whole error message if required.
You need an ID column so hibernate can identify that row in the table. I'm not fluent in that oldschool hibernate xml mapping but it should look roughly like that:
create table course(id integer primary key, course_name varchar2(20));
<class name="Course" table="COURSE" >
<id name="id">
<!-- uses sequence, auto increment or whatever your DBMS uses for id generation -->
<generator class="native"/>
</id>
<property name="course">
<column name="course"/>
</property>
</class>
As a side note: mapping your entities with annotations is a bit more common nowadays. Makes it easier, especially for starters.

Categories