Initial SessionFactory creation failed.org.hibernate.MappingException: Repeated column - java

I am getting following exception while calling a main method.
I am posting mapping file here.
I think this is due to
<list-index>
<column name="bill_no" />
</list-index>
What should be value for this
<hibernate-mapping>
<class name="iland.hbm.BillDetails" table="bill_details" catalog="retail_shop">
<id name="billNo" type="java.lang.Long">
<column name="bill_no" />
<generator class="identity"></generator>
</id>
<many-to-one name="customerDetails" class="iland.hbm.CustomerDetails" fetch="join">
<column name="customer_id" not-null="true" />
</many-to-one>
<property name="subTotal" type="java.lang.Float">
<column name="sub_total" precision="10" />
</property>
<list name="billProductDetailses" table="bill_product_details" inverse="true" lazy="false" fetch="join">
<key>
<column name="bill_no" not-null="true" />
</key>
<list-index>
<column name="bill_no" />
</list-index>
<one-to-many class="iland.hbm.BillProductDetails" />
</list>
</class>
</hibernate-mapping>
Error:
Initial SessionFactory creation failed.org.hibernate.MappingException: Repeated column in mapping for collection: iland.hbm.BillDetails.billProductDetailses column: bill_no
Exception in thread "main" java.lang.ExceptionInInitializerError
at iland.database.HibernateUtil.<clinit>(HibernateUtil.java:32)
at iland.bill.BillDAO.fetchAll(BillDAO.java:94)
Caused by: org.hibernate.MappingException: Repeated column in mapping for collection: iland.hbm.BillDetails.billProductDetailses column: bill_no
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:341)
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:354)
How to resolve above error.

Indeed you are mapping twice the same column in your entity.
<list name="billProductDetailses" table="bill_product_details" inverse="true" lazy="false" fetch="join">
<key>
<column name="bill_no" not-null="true" />
</key>
<list-index>
<column name="bill_no" />
</list-index>
<one-to-many class="iland.hbm.BillProductDetails" />
</list>
When you map twice the same column (bill_product_details.bill_no) in an entity (suppose the properties A and B of your object reference the same column), Hibernate produces that exception because it doesn't know when to update/insert the datum on the db (when A is changed or when B is changed? And what if A and B are different?), so you have to tell it which one is the "master", let's say.
In addition, let me point out that I don't understand your mapping. The "key" should map to the column with the foreign key constraint, while the index should map the column indicating what will be the object's position in your list/array, so I really don't get why they both reference the same column. This way the position of the object in the array will be equal to the id of the referenced entry. Won't it?

Related

Java Hibernate Mapping File not working

The error I get is " org.hibernate.MappingException: Repeated column in mapping for entity: cdd.model.Answer column: answer_id (should be mapped with insert="false" update="false") ". However when I put those as attributes I get the error: "Attribute "insert" must be declared for element type "id"."
Any help would be appreciated.
Class:
public class Answer {
UUID answerID;
String content;
//constructors and getters and setters
}
Table:
CREATE TABLE IF NOT EXISTS answer (
answer_id uuid NOT NULL ,
content text NOT NULL,
primary key(answer_id)
);
Hibernate Mapping File:
<!-->==== Answer ====<!-->
<class name="cdd.model.Answer" table="answer" >
<id column="answer_id" name="answerID"
type="org.hibernate.type.PostgresUUIDType"
insert="false" update="false">
<generator class="org.hibernate.id.UUIDGenerator"/>
</id>
<property column="content" name="content" type="org.hibernate.type.TextType"/>
</class>
Note
I have a Question class where a question has a set of answers. This is the mapping I used. I am posting it because the error I'm gettng may be because of how I mapped this one-to-many relationship (I'm not sure).
<!-- ==== Question ==== -->
<class name="cdd.model.Question" table="question">
<id column="question_id" name="questionID" type="org.hibernate.type.PostgresUUIDType">
< generator class="org.hibernate.id.UUIDGenerator"/>
</id>
<many-to-one column="submitted_by" name="submittedBy" not-null="true"/>
<many-to-one column="parentCategory" name="parentCategory" not-null="true"/>
<property column="title" name="title" type="org.hibernate.type.TextType"/>
<property column="correct_answer" name="correctAnswer" type="org.hibernate.type.TextType"/>
<property column="date_submitted" name="dateSubmitted" type="org.hibernate.type.TimestampType"/>
<set cascade="all" name="answers" table="answer">
<key column="answer_id" not-null="true"/>
<one-to-many class="cdd.model.Answer"/>
</set>
<join inverse="true" optional="true" table="category_questions">
<key column="question_id"/>
</join>
<join inverse="true" optional="true" table="accepted_questions_by_user">
<key column="question_id"/>
</join>
</class>
Question Entity:
<id column="question_id" name="questionID" type="org.hibernate.type.PostgresUUIDType">
<generator class="org.hibernate.id.UUIDGenerator"/>
</id>
Answer Entity:
<id column="answer_id" name="answerID" type="org.hibernate.type.PostgresUUIDType"
insert="false" update="false">
<generator class="org.hibernate.id.UUIDGenerator"/>
</id>
remove insert="false" update="false" from Answr entity
should look someting like this
<id column="answer_id" name="answerID" type="org.hibernate.type.PostgresUUIDType" >
<generator class="org.hibernate.id.UUIDGenerator"/>
</id>
update, insert (optional - defaults to true): specifies that the mapped columns should be included in SQL UPDATE and/or INSERT statements. Setting both to false allows a pure "derived" property whose value is initialized from some other property that maps to the same column(s), or by a trigger or other application.

Hibernate many-to-many with subclasses using the same pivot table

Having this model schema:
Person
|__ Student
|__ SchoolBoy
|__ CollegeStudent
I'm using Hibernate 3.6 and I use the tperson table for all the classes, using a discriminator column. My mapping is done like that:
<class name="Person" table="tperson" discriminator-value="PERSON">
<id name="Id" column="id" type="integer">
<generator class="increment" />
</id>
<discriminator column="person_type" />
<subclass name="Student" discriminator-value="STUDENT">
<key column="id_person" />
<subclass name="SchoolBoy" discriminator-value="SCHOOL_BOY">
<join table="tstudent">
<key column="id_person" />
</join>
</subclass>
<subclass name="CollegeStudent" discriminator-value="COLLEGE_STUDENT">
<join table="tstudent">
<key column="id_person" />
</join>
</subclass>
</subclass>
</class>
Now I want to introduce the Course entity, implementing a relation between courses and students. Of course, this is a many-to-many relation. Let's suppose I use a pivot table named tstudent_course, which contains students of both types SchoolBoy and CollegeStudent. This table contains a reference to the person itself and the course he's studying.
Now I want to differ between college and school students when I load the Course entity. I do it like that:
<set name="CollegeStudents" table="tstudent_course"
inverse="true">
<key>
<column name="id_course" not-null="true" />
</key>
<many-to-many entity-name="CollegeStudent">
<column name="id_person" not-null="true" />
</many-to-many>
</set>
<set name="SchoolStudents" table="tstudent_course"
inverse="true">
<key>
<column name="id_course" not-null="true" />
</key>
<many-to-many entity-name="SchoolBoy">
<column name="id_person" not-null="true" />
</many-to-many>
</set>
However, being the pivot table a table which contains references to every type of students, it tries to load every single student in my collections and I receive the next Exception:
Object with id: 2 was not of the specified subclass:
CollegeStudent (loaded object was of wrong class class SchoolBoy)
It seems Hibernate is doing the join whithout evaluating the concrete type of student I have and tries to inject an SchoolBoy in my collection of College Students.
What can I do to avoid that? Is it possible to stablish a kind of discrimination in the pivot table? Or do I have to create an specific pivot table for each kind of subclass?
In your set you can add a filter:
<set name="CollegeStudents" table="tstudent_course"
inverse="true">
<key>
<column name="id_course" not-null="true" />
</key>
<many-to-many entity-name="CollegeStudent" where="person_type='COLLEGE_STUDENT'">
<column name="id_person" not-null="true" />
</many-to-many>
</set>
IMHO the mapping would be better without that filter (just a set of all students).

Many-to-One w/ Composite key- Foreign key must have same number of columns as he referenced PK

Problem Summary
I am trying to map a many-to-one with a composite key. So far I haven't been able to locate another question that helps. I know how to map to a composite key with one-to-one, but it is not allowing me to map many-to-one.
Below you will see bhrvJournalDAO has a store_nbr column, that maps to transAcctgBuTxtDAO acctg_bu_id. How can I hit the composite key and tell it to only use the acctgBuId? I do not have a country code (which is the second part of the composite key).
From Here
<hibernate-mapping>
<class name="com.acctg.BhrvJournalDAO" table="transpo_acctg:bhrv_journal">
<id name="jeId" column="je_id">
<generator class="native"/>
</id>
<property name="bhrvInvoiceId" column="bhrv_invoice_id"/>
<property name="storeNbr" column="store_nbr"/>
<property name="loadId" column="load_id"/>
<many-to-one name="transAcctgBuTxt" class="TransAcctgBuTxtDAO" insert="false" update="false" cascade="all">
<column name="store_nbr"></column>
</many-to-one>
</class>
To Here
<hibernate-mapping>
<class name="TransAcctgBuTxtDAO" table="transpo_acctg:trans_acctg_bu_txt">
<composite-id name="transAcctgBuTxtPKDAO" class="TransAcctgBuTxtPKDAO">
<key-property name="acctgBuId" column="acctg_bu_id"/>
<key-property name="languageCode" column="language_code"/>
</composite-id>
<property name="acctgBuAbbr" type="java.lang.String">
<column name="acctg_bu_abbr" />
</property>
<property name="acctgBuDesc" type="java.lang.String">
<column name="acctg_bu_desc" />
</property>
<many-to-one name="transAcctgBuDAO" class="TransAcctgBuDAO" not-null="false"
insert="false" update="false" not-found="ignore" fetch="select">
<column name="acctg_bu_id" />
</many-to-one>
</class>
Mapping
<many-to-one name="transAcctgBuTxt" class="TransAcctgBuTxtDAO"
insert="false" update="false" cascade="all">
<column name="store_nbr"></column>
</many-to-one>
Composite Key Example
<one-to-one name="transAcctgBuTxt" class="TransAcctgBuTxtDAO" property-
ref="transAcctgBuTxtPKDAO.acctgBuId">
<column name = "store_nbr">
</one-to-one>
Error
Foreign key (FK47A121BB6617227C:transpo_acct:bhrv_journal [store_nbr]))
must have same number of columns as the referenced primary
key (transpo_acct:trans_acctg_bu_txt [acctg_bu_id,language_code])
Thanks in advance
Since TransAcctgBuTxtDAO has the composite id of 2 columns, you NEED to provide both values to uniquely identify one entity, period. Maybe you could reconsider if it is really a many-to-one relation between BhrvJournalDAO and TransAcctgBuTxtDAO. Mabye it is actually many-to-many.

How to set a null in the database for the integer field using hibernate?

I am trying to update a field in the database to null for an integer field. I am trying to do that using hibernate. I can set object field like String and any other object to null but no integer.
<?xml version="1.0" encoding="UTF-8"?>
<class name="App_Users" table="app_users" schema="bidtool">
<id name="userId" type="int" column="user_id">
<generator class="assigned"/>
</id>
<property name="username" type="string">
<column name="username" length="20" not-null="true" />
</property>
<property name="password" type="string">
<column name="password" length="20" not-null="true" />
</property>
<property name="firstname" type="string">
<column name="firstname" length="20" />
</property>
<property name="lastname" type="string">
<column name="lastname" length="20" />
</property>
<property name="userType" type="int">
<column name="user_type" />
</property>
<many-to-one class="MasterOrg" fetch="select" name="masterOrg">
<column name="master_org_id" />
</many-to-one>
<many-to-one class="CarrierScac" fetch="select" name="carrierScac">
<column name="scac" />
</many-to-one>
<one-to-one class="AppUserDetails" fetch="select" name="details" constrained="true"/>
<set name="profiles" inverse="true">
<key>
<column name="user_id" />
</key>
<one-to-many class="Profiles" />
</set>
<set name="boilerPlates" inverse="true">
<key>
<column name="user_id" />
</key>
<one-to-many class="BoilerPlate" />
</set>
<set name="rates" inverse="true" >
<key>
<column name="user_id" />
</key>
<one-to-many class="BidToolRates" />
</set>
</class>
In the above hibernate mapping code, I want to set MasterOrg field as null.
It is best to use the object wrappers for the primitive types i.e. Integer for int, Double for double, ... etc because primitive types don't allow for the possibility of null which is always possible in a database design.
Even if a value is declared not null in the database an Object type is still useful. Consider the follow scenario as an example.
#Entity
public class ExampleEntity {
#Column(name="some_column") // assume this column is defined not null in the database
private int someProperty;
getttes settters other fields go here
}
Assume you write the following code
ExampleEntity t = new ExampleEntity();
entityManager.persist(t);
In this example t.someProperty has a value of 0 because that is the default value for an int therefore entityManager.persist works but maybe 0 is not a valid value for that column. If you have database constraints on that column then you get an error otherwise you have bad data in the database.
If someProperty was declared with wrapper type of Integer and the developer forgets to set the somePorpety value then you will get a not null exception.
A second reason to always use wrappers is simplicity as a developer I want consistent structure across entities because code is read more often that it is written so universally using wrapper types on entities makes things predictable for some one maintaining the code 5 years from now.

Hibernate One To Many Unidirectional Mapping List

I have one-to-many relationship between parent and child Java objects. The parent object uses java.util.List that stores multiple child objects. The problem I am experiencing is when updating the parent object after I have added one or more child object(s) to the List in the parent. I am using the saveOrUpdate method to save or update the parent. It works fine if I am saving a new instance of the parent, but after saving it, I try to add child object(s) into the parent List and then attempt to call saveOrUpdate on the parent object, but no entries of child object(s) get persisted into the database. I just would like some pointers. Note: I am not using annotations. A snippet of the Parent.hbm.xml, that defines the one-to-many unidirectional relationship:
<list name="children" cascade="all">
<key column="parent_id"/>
<index column="idx"/>
<one-to-many class="Child"/>
</list>
I just tried to reproduce this example and it worked OK for me.
Here are my mappings:
<hibernate-mapping package="com.example.domain">
<class name="com.example.domain.Parent" table="PARENT">
<id name="id" column="parent_id" access="field">
<generator class="increment" />
</id>
<property name="name" column="parent_name" access="field" />
<list name="children" access="field" cascade="all">
<key column="parent_id" not-null="true" />
<index column="idx" />
<one-to-many class="Child" />
</list>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.example.domain">
<class name="com.example.domain.Child" table="CHILD">
<id name="id" column="child_id" access="field">
<generator class="increment" />
</id>
<property name="name" column="child_name" access="field" />
</class>
</hibernate-mapping>
I added not-null="true" to the parent mapping.
Did you try to set show_sql in your hibernate config to see generated SQL?

Categories