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.
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 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
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
When I use hibernate eclipse plugin to generate java class from my table, the private field name is the same with my table name. Is there a way for me to make it to be the same with my column name instead?
For example:
table: User
column : name (string)
column : homeAddressId (fk to addressTable)
The generated class right now is:
User{
private String name;
private Address address;
}
I want it to be:
User{
private String name;
private Address homeAddress;
}
Is there a settings to do that?
Thanks very much for your help.
there can be problem in the understanding between you and hibernate. Actually, what i see, there is a foreign key with other table which is Address, not homeAddress.
can you also post the other table(Address) structure.
as if the other table name is Address then hibernate plugin is bond to create create attribute with name address, as i feel plugin doesn't have intelligence of its own.
Before anything, your domain should be the way you want it. If you need to make more changes to the mapping (ORM), you might need to do it in your hibernate-conf.xml. The generated class and the current class is the same. For example the user.xml will be something like this:
<?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="User" table="ADMIN_USER_TBL">
<id name="id" type="string" column="ADMIN_USER_ID">
<generator class="assigned" />
</id>
<property name="name" column="FIRST_NAME" />
...
</class>
</hibernate-mapping>
Then, have the mapping for the address:
<?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="Address" table="ADDRESS_TBL">
<id name="id" type="string" column="ADMIN_USER_ID">
<generator class="assigned" />
</id>
<property name="address" column="ADDRESS1" />
<property name="address2" column="ADDRESS2" />
<property name="city" column="ADDRESS_CITY" />
<property name="state" column="ADDRESS_STATE" />
<property name="zip" column="ADDRESS_ZIP" />
...
</class>
</hibernate-mapping>
Let me know if that helps! ;)
Hello guys sorry if the question looks stupid to you.
i have 3 tables currency (id | name) language (id| name | description) transaction (id|amount|languageId | currencyid)
so i want to insert into the transaction but making sure that it doesn't insert unknown language or currency (meaning it shouldn't insert to messagetemplate if there is no existing parent language and currency)
here are my mapping files
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.myproject.model">
<class name="Transaction" table="transaction">
<id name="id">
<generator class="native"/>
</id>
<property column="amount" name="amount" type="String"/>
<many-to-one class="CurrencyImpl" column="currency" name="currency"/>
<many-to-one class="LanguageImpl" column="language" name="language"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.myproject.model">
<class name="Currency" table="currency">
<id name="id">
<generator class="native"/>
</id>
<property column="currency_name" name="name" type="String"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.myproject.model">
<class name="Language" table="language">
<id name="id">
<generator class="native"/>
</id>
<property column="language_name" name="name" type="String"/>
<property column="language_description" name="description" type="String"/>
</class>
</hibernate-mapping>
with this current mapping it's seems not to be the case.how to achieve that? thanks a lot for reading
You're many to one references CurrencyImpl and LanguageImpl, but those classes are not mapped, only the (presumably corresponding) interfaces. I suggest you begin by creating and mapping only concrete classes and get that working before trying to mess about with mapping interfaces.