I am getting the following error when I try to execute a join query
("could not resolve property: Countries of: com.fexco.helloworld.web.model.Customer [select cus from com.fexco.helloworld.web.model.Customer as cus join cus.Countries as cou where cus.id = cou.id]")
I am trying to join the Customer and Countries tables together by a common id
Customer.hbm.xml
<?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 package="com.ccg.db.test">
<class name="Customer" table="Customer">
<id name="id" column="id" type="bigiint">
<generator class="native"/>
</id>
<property name="firstname" type="string" >
<column name="firstname" />
</property>
<property name="surname" type="string" >
<column name="surname" />
</property>
<property name="address1" type="string" >
<column name="address1" />
</property>
<property name="address2" type="string" >
<column name="address2" />
</property>
<many-to-one name="Countries" column="id" class="Countries" />
</class>
</hibernate-mapping>
Countries.hbm.xml
<?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 package="com.ccg.db.test">
<!-- CLASS NAME MIGHT BE CUSTOMER -->
<class name="Countries" table="Countries">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="country" column="country" />
</class>
</hibernate-mapping>
And this is the query that i am trying to call
String sql_query = "select cus from Customer as cus join cus.Countries as cou where cus.id = cou.id";
I am new to HQL so not sure about everything with it yet so does anybody know how to solve this?
Thanks
It's cus.countries, not cus.Countries. Property names are case sensitive.
try
select cus from Customer cus where cus.id = cus.countries.id
Related
I want to create relation between Definition (DEF) and Details (DET) table by foreign keys in Hibernate. In this case, one definition has multiple details.
Definition table has ID column as PK
Details table has ID column as PK and DEFINITION_ID as FK
When I connect these inside of hbm.xml I am getting an error such as;
ERROR
Caused by: org.hibernate.MappingException: Repeated column in mapping
for entity: com.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDet
column: ID (should be mapped with insert="false" update="false")
DEFINITION HBM XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!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.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDef"
table="CMS_EXEMPT_RESTRICT_DEF">
<tuplizer class="com.ykb.hmn.inf.core.datamodel.IntfEntityTuplizer"
entity-mode="pojo" />
<id name="oid" type="java.lang.Long">
<column name="ID" />
<generator class="sequence">
<param name="sequence">SEQ_CMS_EXEMPT_RESTRICT_DEF</param>
</generator>
</id>
.
.
.
<bag name="cmsExemptRestrictDetails" table="CMS_EXEMPT_RESTRICT_DET"
inverse="true" lazy="true" fetch="select">
<key>
<column name="DEFINITION_ID" not-null="true" />
</key>
<one-to-many
class="com.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDet" />
</bag>
</class>
</hibernate-mapping>
DETAIL HBM XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!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.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDet"
table="CMS_EXEMPT_RESTRICT_DET">
<tuplizer class="com.ykb.hmn.inf.core.datamodel.IntfEntityTuplizer"
entity-mode="pojo" />
<id name="oid" type="java.lang.Long">
<column name="ID" />
<generator class="sequence">
<param name="sequence">SEQ_CMS_EXEMPT_RESTRICT_DET</param>
</generator>
</id>
<many-to-one name="cmsExemptRestrictDefinition" class="com.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDef" fetch="select">
<column name="ID" not-null="true" />
</many-to-one>
<property name="definitionId" type="java.lang.Long">
<column name="DEFINITION_ID" />
</property>
</class>
</hibernate-mapping>
First - Do I need to define both many to one and one to many relation in each hbm xmls?
Second - Do I need to rename column ID of Detail something like DETAIL_ID?
Thanks.
The property mapping Definition_id is incorrect. The foreign key should not be mapped. Remove it and change the column name in manytoone mapping to definition_id:
Change the detail hbm xml to:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!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.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDet"
table="CMS_EXEMPT_RESTRICT_DET">
<tuplizer class="com.ykb.hmn.inf.core.datamodel.IntfEntityTuplizer"
entity-mode="pojo" />
<id name="oid" type="java.lang.Long">
<column name="ID" />
<generator class="sequence">
<param name="sequence">SEQ_CMS_EXEMPT_RESTRICT_DET</param>
</generator>
</id>
<many-to-one name="cmsExemptRestrictDefinition" class="com.ykb.hmn.cms.commission.datamodel.ICmsExemptRestrictDef" fetch="select">
<column name="DEFINITION_ID" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
I have an AbstractAccount hbm file where i set accountNumber as primarykey. I'am extending this class in my Account.hbm.xml file where I want to over ride this primary key as countryCode and accountNumber composite key. How can i do this?
Abstract.hbm.xml file.
<?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.*.*.*.AbstractAccount"
abstract="true"
table="ACCOUNT"
lazy="false">
<id name="accountNumber" type="java.lang.String">
<column name="ACCOUNT_NUMBER" length="16" />
<generator class="assigned" />
</id>
<discriminator column="ACCOUNT_TYPE" type="string"/>
................
</class>
</hibernate-mapping>
Account.hbm.xml
<property name="modifiedDate" type="java.util.Date">
<column name="MODIFIED_DATE"/>
</property>
<property name="countryCode" type="java.lang.String">
<column name="COUNTRY_CODE"/>
</property>
...............
</subclass>
I have tried with adding composite key as below, but it is not working.
<composite-id name="account_country">
<key-property name="countryCode" column="COUNTRY_CODE" />
<key-property name="accountNumber" column="ACCOUNT_NUMBER" />
</composite-id>
Abstract.hbm.xml
<hibernate-mapping>
/* Abstract class properites */
<joined-subclass name="Account" table="tablename">
/* Account class properites */
</join-subclass>
</hibernate-mapping>
I have a poor time performance in a SqlQuery under Hibernate 3.6.9 Final with a DB2 database. The sql is made quickly from the SQL Client (Squirrel):
Query 1 of 1, Rows read: 175, Elapsed time (seconds) - Total: 0.527, SQL query: 0.233, Reading results: 0.29
I'm using a ResultTransformer of my own, but it works fine and quickly (I have measured times).
I have been looking the times all around and I found that all the time (about 12 seconds!!!) is lost when the org.hibernate.loader.Loader is making some calls to its methods:
11:21:17,026 DEBUG 127.0.0.1 - MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[426] - about to open ResultSet (open ResultSets: 0, globally: 0)
11:21:17,205 DEBUG 127.0.0.1 - MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
11:21:17,272 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
...175 rows all the same...
11:21:27,978 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
11:21:28,037 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
11:21:28,096 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[433] - about to close ResultSet (open ResultSets: 1, globally: 1)
11:21:28,097 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[418] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
As you can see here at the logs on the left, about 11 seconds are spent. I googled on this Hibernate Class and found the source code here: http://goo.gl/6oAXLT and came to the conclussion that the getRow() method from the Loader is making 1 query per row (total: 175 times) for cheking the ids and so on, but I don't know how to disable this behaviour or which is the configuration I should modify for avoiding this delay.
My mappings are:
Main object (Request):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.request.Request"
table="REQUEST" schema="${db2.app.schema}">
<id name="id" type="java.lang.Long" access="field">
<column name="REQUEST_ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
<property name="improvement" type="java.lang.String">
<column name="BENEFIT" not-null="true" />
</property>
<property name="startScheduledDate" type="java.util.Date">
<column name="START_SCHEDULED_DATE" not-null="false" />
</property>
<property name="createTimestamp" type="java.sql.Timestamp">
<column name="CREATE_DATE" not-null="true" />
</property>
<property name="createUser" type="java.lang.String">
<column name="CREATE_USER" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
Lac:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.lac.Lac"
table="REQUEST_ENTERPRISE_AREA" schema="${db2.app.schema}">
<composite-id name="id"
class="com.enterprise.myappweb.model.requests.lac.LacId">
<key-property name="requestId" type="java.lang.Long">
<column name="REQUEST_ID" not-null="true" />
</key-property>
<key-property name="lacId" type="java.lang.Integer">
<column name="ENTERPRISE_AREA_ID" not-null="true" />
</key-property>
</composite-id>
<property name="order" type="java.lang.Integer">
<column name="ORDER" not-null="true" />
</property>
<property name="startScheduledDate" type="java.util.Date">
<column name="START_SCHEDULED_DATE" not-null="false" />
</property>
<property name="finalScheduledDate" type="java.util.Date">
<column name="END_SCHEDULED_DATE" not-null="false" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
PriorityType:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.type.PriorityType"
table="PRIORITY_TYPE_REQUEST" schema="${db2.app.schema}">
<id name="id" type="java.lang.Short" access="field">
<column name="PRIORITY_TYPE_REQUEST_ID" />
<generator class="native" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
Status:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.type.Status"
table="REQUEST_STATUS" schema="${db2.app.schema}">
<id name="id" type="java.lang.Short" access="field">
<column name="REQUEST_STATUS_ID" />
<generator class="native" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
RequestType:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.type.RequestType"
table="REQUEST_TYPE_REQUEST" schema="${db2.app.schema}">
<id name="id" type="java.lang.Short" access="field">
<column name="REQUEST_TYPE_REQUEST_ID" />
<generator class="native" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
Java code:
#Repository("requestDao")
public class RequestDaoHibernate extends AbstractReadWriteDao<Request, Long> implements RequestDao {
#Override
public List<Request> findRequests(final RequestSearchDto requestSearchDto, final Boolean isWarehouseUser) {
queryString = "SELECT .... FROM ...."; // Long string
List<Request> result = this.listSQLQuery(queryString.toString(), new SQLQueryCallback() {
#Override
public void doWithQuery(final SQLQuery query) {
// Recuperamos idiomas (del usuario y por defecto) a través de spring
String idiom = LocaleContextHolder.getLocale().getLanguage().toUpperCase();
query.setParameter("isoCodeLanguageId", 3);
query.setParameter("defaultLanguageId", 1);
for(Entry<String, Object> e : dictionary.entrySet()) {
if(e.getKey().endsWith("List")) {
query.setParameterList(e.getKey(), (Collection)e.getValue());
} else {
query.setParameter(e.getKey(), e.getValue());
}
}
RequestSearchRT rt = new RequestSearchRT();
query.setResultTransformer(rt);
}});
return result;
}
}
SuppressWarnings({"unchecked"})
public <S> List<S> listSQLQuery(final String sqlQuery,
final SQLQueryCallback callback) {
if (LOG.isDebugEnabled()) {
LOG.debug("Listing elements with SQL query: {}", sqlQuery);
}
return (List<S>) getHibernateTemplate().execute(new HibernateCallback() {
#Override
public List<S> doInHibernate(final Session session) throws SQLException {
SQLQuery query = session.createSQLQuery(sqlQuery);
callback.doWithQuery(query);
return query.list();
}
});
}
}
I will update the post with configuration settings as people ask me, because I think all the config is in several files and are big.
Thanks in advance.
I have two tables in a MySQL database: COURSE and COURSE_SESSION.
COURSE has two fields : code(primary key) and title.
CourseSession has a field called course_code which is a foreign key linked to an element of Course.
I want to do somthing like this but using the Criteria API in Java :
SELECT * FROM COURSE_SESSION join COURSE
WHERE course_code = code AND title like "%substring%";
Both tables are mapped correctly with hibernate.
I tried this :
Criteria criter = s.createCriteria(CourseSession.class);
criter.add(Restrictions.like("courseCode.title", "%substring%"));
But I end up with an error :
HTTP 500 - could not resolve property: courseCode.title of: org.xxx.core.entity.CourseSession
message could not resolve property: courseCode.title of: org.xxx.core.entity.CourseSession
exception
org.hibernate.QueryException: could not resolve property: courseCode.title of: fr.utbm.lo54.core.entity.CourseSession
org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81)
org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:96)
org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:62)
org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1443)
org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:483)
org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:443)
org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:68)
org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:380)
org.hibernate.loader.criteria.CriteriaJoinWalker.(CriteriaJoinWalker.java:114)
org.hibernate.loader.criteria.CriteriaJoinWalker.(CriteriaJoinWalker.java:83)
org.hibernate.loader.criteria.CriteriaLoader.(CriteriaLoader.java:92)
org.hibernate.impl.SessionImpl.list(SessionImpl.java:1687)
org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
fr.utbm.lo54.core.servlet.SearchData.doGet(SearchData.java:52)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
The strange thing is that if I do a Restriction on courseCode.code with Restrictions.like("courseCode.code", "%substring%"), it works fine.
EDIT
Course.hbm.xml :
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.xxx.core.entity">
<class name="Course" table="COURSE">
<id name="code" column="CODE">
<generator class ="identity"/>
</id>
<property name="title" column="TITLE" not-null="true"/>
</class>
</hibernate-mapping>
CourseSession.hbm.xml :
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.xxx.core.entity">
<class name="CourseSession" table="COURSE_SESSION">
<id name="id" column="ID">
<generator class="identity" />
</id>
<property name="startDate" column="START_DATE" not-null="true" />
<property name="endDate" column="END_DATE" not-null="true" />
<many-to-one name="courseCode" column="COURSE_CODE" />
<many-to-one name="locationId" column="LOCATION_ID" />
</class>
</hibernate-mapping>
create an alias for the field first to achieve this.
try the below code, it should help
criter.createAlias("courseCode","courseCode");//course code is the association variable in your pojo class.
I have three tables. Order, Location, Order_Location where Order_Location is table that holds many-to-many relation.
Order has List<Location>. Location has property called city. Using HQL (Hibernate 3.6 for Java), I want to get all the locations for a particular order, ordered by the city.
In hbm file, List<Location> is mapped using idbag. Though I got the HQL, the generated SQL query is having join to Location and Order_Location table twice which I feel is overhead.
What am I doing wrong here?
SELECT o.locationList FROM Order o
join o.locationList locList
where o.orderId = 1
order by locList.city desc
which translates to something like below
select
order4_.LOC_ID as order1_355_,
order4_.LOC_CODE as order2_355_,
order4_.CITY as order3_355_,
order4_.CITY_LONG_NAME as order4_355_
from
sche.order order0_
inner join
sche.order_location order1_
on order0_.ORDER_ID=order1_.ORDER_ID
inner join
sche.location order2_
on order1_.LOC_ID=order2_.LOC_ID
inner join
sche.order_location order3_
on order0_.ORDER_ID=order3_.ORDER_ID
inner join
sche.location order4_
on order3_.LOC_ID=order4_.LOC_ID
where
order0_.ORDER_ID=1
order by
order2_.city desc
========= EDIT
Order.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"
>
<hibernate-mapping>
<class name="collectionorderby.Order" table="ORDER">
<id name="orderId" type="string">
<column name="ORDER_ID" length="32" />
<generator class="uuid" />
</id>
<idbag name="locationList" lazy="false" table="ORDER_LOCATION" fetch="select">
<collection-id column="ORDER_LOCATION_ID" type="string">
<generator class="uuid" />
</collection-id>
<key>
<column name="ORDER_ID" length="32" not-null="true" />
</key>
<many-to-many column="LOC_ID" class="collectionorderby.Location"
fetch="join" />
</idbag>
</class>
</hibernate-mapping>
Location.hbm.xml
<?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="collectionorderby.Location" table="LOCATION">
<id name="locId" type="string">
<column name="LOC_ID" length="50" />
</id>
<property name="locCode" type="string">
<column name="LOC_CODE" length="50" />
</property>
<property name="city" type="string">
<column name="CITY" length="50" />
</property>
<property name="cityLongName" type="string">
<column name="CITY_LONG_NAME" length="500" />
</property>
</class>
</hibernate-mapping>
==== EDIT
Noticed that when we provide order by, translated query gets the select from first instance of table where as the order by is done using the second instance of the table. This will not happen, I suppose, if we avoid the duplicate instance of these tables.
The following worked as expected. The alias locList was used in select instead of o.locationList
SELECT locList FROM Order o join o.locationList locList where o.orderId = 1 order by locList.city desc