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>
Related
I have a Project that contains a Set of Columns that contains a Set of Tasks that contains a Set of TaskAssigness.
I'm trying to update a column title without having to load its set of tasks, but I get the following error :
[AssertionFailure] - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: collection [com.example.tasks.Task.taskAssignees] was not processed by flush()
I have the following hbm.xml :
Project.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"classpath://org/hibernate/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.exemple.tasks.project.Project" table="P_TASKS_PROJECT">
<cache usage="read-write" />
<id name="rowId" column="rowId">
<generator class="native"/>
</id>
...
<set name="columns" table="P_TASK_PROJECT_COLUMN" inverse="true" cascade="all" sort="com.exemple.tasks.project.ColumnIndexComparator">
<cache usage="read-write" />
<key column="projectId" not-null="true" />
<one-to-many class="com.exemple.tasks.project.Column" />
</set>
</class>
</hibernate-mapping>
Column.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"classpath://org/hibernate/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.example.tasks.project.Column" table="P_TASK_PROJECT_COLUMN">
<cache usage="read-write" />
<id name="rowId" column="rowId">
<generator class="native"/>
</id>
...
<property name="title" />
<many-to-one name="project" class="com.example.tasks.project.Project">
<column name="projectId" not-null="false" />
</many-to-one>
<set name="tasks" table="P_TASKS_JOIN_COLUMNS">
<cache usage="read-write" />
<key column="columnId" not-null="true" />
<many-to-many column="taskId" class="com.example.tasks.Task" unique="false" />
</set>
</class>
</hibernate-mapping>
Task.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"classpath://org/hibernate/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.example.tasks.Task" table="P_TASK">
<cache usage="read-write" />
<id name="rowId" column="rowId">
<generator class="native"/>
</id>
...
<set name="taskAssignees" table="P_TASK_ASSIGNEE" cascade="all-delete-orphan">
<cache usage="read-write" />
<key column="taskId" not-null="true" />
<one-to-many class="com.example.tasks.TaskAssignee" />
</set>
</class>
</hibernate-mapping>
TaskAsignee.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"classpath://org/hibernate/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.example.tasks.TaskAssignee" table="P_TASK_ASSIGNEE">
<cache usage="read-write" />
<id name="rowId" column="rowId">
<generator class="native"/>
</id>
...
<many-to-one name="task" class="com.example.tasks.Task" insert="false" update="false">
<column name="taskId" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
I'm trying to update the title of a column this way :
//Updating column title
Column column = project.getColumn(index); // return a column from the project. Project contains a SortedSet of Column
column.setTitle("NewTitle");
session.saveOrUpdate(project);
This works fine if the column does not contains any tasks.
If I try to update a column containing tasks I get the following error message:
[AssertionFailure] - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: collection [com.example.tasks.Task.taskAssignees] was not processed by flush()
If i get tasks and tasks assigness before updating the project, I have no errors :
Set<Task> tasks = col.getTasks();
if (tasks != null) {
for (Task task : tasks) {
task.getTaskAssignees();
}
}
session.saveOrUpdate(project);
Is there a way to change my column title, then update the project without having to get tasks and task assignees ? Can I tell hibernate just to update the column and not try to go further.
I am working on an application that saves employee data using jsf 1.2, richfaces 3.3, for ORM i am using hibernate 3. I am saving data in 'Employee' basic table about two fields i.e Present City and Permanent City. The City values come from a lookup table 'City' . my hbm file for the employee table has following code:-
<many-to-one name="presentcity" cascade="lock" column="PRESENT_CITY_ID"
class="org.lookups.City" lazy="false">
</many-to-one>
<many-to-one name="permanentcity" cascade="lock" column="PERM_CITY_ID"
class="org.lookups.City" lazy="false">
</many-to-one>
this question did not help as it uses annotations and i need to work with hbm file. The problem is, when i update one of the presentcity or permanentcity, both the values are changed.
structure of my tables is as follows:-
employee table
________________________________________________________
emp_id name age PRESENT_CITY_ID PERM_CITY_ID
________________________________________________________
203 paul 28 3 7
. . . . .
301 ferris 29 6 9
_________________________________________________________
city lookup table
______________________
id city
______________________
3 Chicago
. .
6 Cairo
. .
9 Wales
______________________
The hibernate.cfg.hbm files for both employee and city are as follows:-
<?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>
<class name="org.Employee" table="EMP_MAIN">
<id name="empId" type="long" column="EMP_ID">
<generator class="increment"></generator>
</id>
<property name="emp_No" type="long" column="EMP_NO" />
<property name="name" type="string" column="NAME" />
<many-to-one name="presentcity" class="org.lookups.City"
fetch="select" cascade="none">
<column name="PRESENT_CITY_ID" precision="22" scale="0"
not-null="false">
<comment>present city of the employee</comment>
</column>
</many-to-one>
<many-to-one name="permanentcity" class="org.lookups.City"
fetch="select" cascade="none">
<column name="PERM_CITY_ID" precision="22" scale="0"
not-null="false">
<comment>permanent city of the employee</comment>
</column>
</many-to-one>
</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>
<class name="org.lookups.City" table="LU_CITY">
<id name="id" type="long" column="CITY_ID">
<generator class="increment"></generator>
</id>
<property name="city" type="string" column="CITY_NAME" />
</class>
</hibernate-mapping>
how to get around this problem.
I've adapted this from a working hbm file that we use at our company so I know it works. It includes the column name for mapping. Maybe that is what you're missing?
<many-to-one name="presentcity" class="org.lookups.City" fetch="select" cascade="none">
<column name="PRESENT_CITY_ID" precision="22" scale="0" not-null="false">
<comment>the present city of the employee</comment>
</column>
</many-to-one>
<many-to-one name="permanentcity" class="org.lookups.City" fetch="select" cascade="none">
<column name="PERM_CITY_ID" precision="22" scale="0" not-null="false">
<comment>the permanent city of the employee</comment>
</column>
</many-to-one>
Good luck.
I try to understand hibernate but it is very hard.
I have a problem now that i don't really understand. Its about the many-to-many relations in my mapping file. If I save an object it wont save the "many" in my DB but it wont save it. I think it is in my mapping but i don't see it.
It's about flight and staff on the plane. When I save the plane the staff members must be save with it. But that wont happen.
Here is my mapping of both:
The Flight 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">
<!-- Generated 28-sep-2012 11:49:37 by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class name="model.Flight" table="flights" catalog="flyaway_db">
<id name="number" type="int">
<column name="FlightNumber" />
<generator class="assigned" />
</id>
<set name="staffs" table="flightstaff" cascade="save-update">
<key>
<column name="FlightNumber" not-null="true" />
</key>
<many-to-many class="model.Staff">
<column name="StaffNumber" length="5" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>
The staff 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">
<!-- Generated 28-sep-2012 11:49:37 by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class name="model.Staff" table="staff" catalog="flyaway_db">
<id name="staffNumber" type="string">
<column name="StaffNumber" length="5" />
<generator class="assigned" />
</id>
<set name="flightses" table="flightstaff" cascade="save-update">
<key>
<column name="StaffNumber" length="5" not-null="true" />
</key>
<many-to-many class="model.Flight">
<column name="FlightNumber" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>
You forgot the inverse="true" on one side of the bidirectional relationship.
Sorry for all the question but it was the model that wasn't correct! and i think Pache answer also helped!
Thanks all
I have a many to many (with a join table) relationship in my database that I need to model in hibernate.
I have POJO classes for all three tables in the database as the join table contains more than just the mapping information.
My problem occurs on save() of class A where class A is told to cascade to class AB (the join table) which is told to cascade to class B, but when it gets to the point where it is saving AB the foriegn key reference to table A is null.
At the end of the day I want to be able to call save() on an instance of the TableA class and have it save all three tables.
Table Diagram
TABLE A 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">
<!-- Generated Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.example.dbtables.TableA" table="Table A">
<id name="id" type="int">
<column name="id" />
<generator class="sequence">
<param name="sequence">table_a_seq</param>
</generator>
</id>
<natural-id>
<property name="data1" type="int">
<column name="DATA1" not-null="true" />
</property>
<property name="data2" type="string">
<column name="DATA2" length="16" not-null="true" />
</property>
</natural-id>
<set name="tableAB" cascade="save-update" table="TableAB" inverse="true" lazy="true" fetch="select">
<key>
<column name="Table_AB_ID" not-null="true" />
</key>
<one-to-many class="com.example.dbtables.TableAB" />
</set>
</class>
</hibernate-mapping>
TABLE AB 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">
<!-- Generated Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.example.dbtables.TableAB" table="Table AB">
<id name="id" type="int">
<column name="id" />
<generator class="sequence">
<param name="sequence">table_ab_seq</param>
</generator>
</id>
<natural-id>
<many-to-one name="tableA" class="com.example.dbtables.TableA" fetch="select">
<column name="Table_A_ID" not-null="true" />
</many-to-one>
<many-to-one name="tableB" cascade="save-update" class="com.example.dbtables.TableB" fetch="select">
<column name="Table_B_ID" not-null="true" />
</many-to-one>
<property name="data1" type="int">
<column name="DATA1" not-null="true" />
</property>
<property name="data2" type="int">
<column name="DATA2" not-null="true" />
</property>
</natural-id>
</class>
</hibernate-mapping>
TABLE B 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">
<!-- Generated Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.examples.dbtables.TableB" table="Table B">
<id name="id" type="int">
<column name="id" />
<generator class="sequence">
<param name="sequence">table_b_seq</param>
</generator>
</id>
<natural-id>
<property name="data1" type="string">
<column name="DATA1" length="16" />
</property>
<property name="data2" type="java.lang.Integer">
<column name="DATA2" />
</property>
</natural-id>
<set name="TableAB" table="Table AB" inverse="true" lazy="true" fetch="select">
<key>
<column name="Table_AB_ID" not-null="true" />
</key>
<one-to-many class="com.example.dbtables.TableAB" />
</set>
</class>
</hibernate-mapping>
Thanks for any help you can give. Let me know if you need clarification or anymore information.
EDIT: My problem was that the references from AB -> to A were not getting correctly populated. This issue has been resolved thanks to everyone who helped.
A a = new A();
B b = new B();
AB ab = new AB();
ab.setA(a);
ab.setB(b);
a.setAB(ab);
b.setAB(ab);
save(a);
This example not working? Did you get some exception?
EDIT
Look into this Hibernate doc Chapter 5. Basic O/R Mapping to chapter 5.1.4.1. Generator
PostgreSQL doesn't support identity generation type.
Use sequence generation instead of identity, or something else
The problem was that the back references between AB -> A were not getting correctly populated in my code. Thanks to Ilya for the help.
I am trying to make hibernate load my whole tree with no success.
I have a schema like this
A Category can have many attribute and an attribute can have many options
Category
--->Attribute1
--->AttributeOption1
--->AttributeOption3
--->Attribute2
--->AttributeOption1
--->AttributeOption1
but when I am using hibernate, it is not loading the whole tree:
my mapping file are:
Attribute Mapping 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">
<!-- Generated Dec 16, 2010 5:25:09 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.Attribute" table="ATTRIBUTE">
<id name="AttributeId" type="long">
<column name="ATTRIBUTEID" />
<generator class="native" />
</id>
<property name="AttributeName" type="java.lang.String">
<column name="ATTRIBUTENAME" />
</property>
<set name="Options" table="ATTRIBUTEOPTION" inverse="false" cascade="all" lazy="true">
<key>
<column name="ATTRIBUTEID" />
</key>
<one-to-many class="com.BiddingSystem.Models.AttributeOption" />
</set>
</class>
</hibernate-mapping>
Attribute Option Mapping 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">
<!-- Generated Dec 16, 2010 5:25:09 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.AttributeOption" table="ATTRIBUTEOPTION">
<id name="AttributeOptionId" type="long">
<column name="ATTRIBUTEOPTIONID" />
<generator class="native" />
</id>
<property name="Option" type="java.lang.String">
<column name="OPTION" />
</property>
<property name="SQLValue" type="java.lang.String">
<column name="SQLVALUE" />
</property>
</class>
</hibernate-mapping>
Category Mapping 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">
<!-- Generated Dec 16, 2010 8:37:02 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.Category" table="CATEGORY">
<id name="CategoryId" type="long">
<column name="CATEGORYID" />
<generator class="native" />
</id>
<property name="CategoryName" type="java.lang.String">
<column name="CATEGORYNAME" />
</property>
<many-to-one name="ParentCategory" class="com.BiddingSystem.Models.Category">
<column name="PARENT_CATEGORY_ID" />
</many-to-one>
<set name="SubCategory" lazy="true" cascade="all-delete-orphan" inverse="true">
<key>
<column name="PARENT_CATEGORY_ID" />
</key>
<one-to-many class="com.BiddingSystem.Models.Category" />
</set>
<set name="AllAttributes" table="ATTRIBUTE" inverse="false" lazy="true" cascade="all">
<key>
<column name="CATEGORYID" />
</key>
<one-to-many class="com.BiddingSystem.Models.Attribute" />
</set>
</class>
</hibernate-mapping>
The function that loads the parent category are:
public List <Category> getCategory(long CategoryId)
{
Session session = gileadHibernateUtil.getSessionFactory().openSession();
List <Category> AllCategory= new LinkedList<Category> ();
String SQL="from Category where parent_category_id is NULL";
Query query = session.createQuery(SQL);
return query.list();
}
Make all your associations lazy=false; by default the lazy = true
I believe there is an other mistake:
String SQL="from Category where parent_category_id is NULL";
Query query = session.createQuery(SQL);
org.hibernate.Session.createQuery(String queryString) requires a HQL Query String, but not a SQL query! And from Category where parent_category_id is NULL seems to be a SQL query, because parent_category_id is a column name but not a property / field name.