org.hibernate.MappingException: Association references unmapped class - java

The configuration for User class :
<class name="User" table="users" lazy="false">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="type" column="type"/>
<many-to-one name="parent" column="parent"/>
<property name="loginName" column="login_name" unique="true" not-null="true" index="idx_users_login_name" length="50"/>
<property name="name" column="name" length="50"/>
<property name="password" column="password"/>
<property name="email" column="email" length="50"/>
<property name="locale" column="locale" length="20"/>
<property name="locked" column="locked"/>
<many-to-one name="metadata" column="metadata_id"/>
<set name="userSpaceRoles" cascade="all" inverse="true" lazy="false">
<key column="user_id"/>
<one-to-many class="UserSpaceRole"/>
</set>
</class>
and for the class MeetingItem is:
<class name="MeetingItem" table="meeting_item">
<id name="id" column="meeting_item_id" type="long">
<generator class="native"/>
</id>
<property name="summary" column="summary" type="string"/>
<property name="detail" column="detail" type="string"/>
<many-to-one name="space" column="space_id"/>
<property name="date" column="date" type="date"/>
<list name="users" cascade="all" lazy="false">
<key column="meeting_item_id"/>
<index column="idx"/>
<one-to-many class="User"/>
</list>
</class>
The problem is I am getting the exception:
org.hibernate.MappingException: Association references unmapped class: info.domain.User
at org.hibernate.cfg.HbmBinder.bindCollectionSecondPass(HbmBinder.java:2380)
at org.hibernate.cfg.HbmBinder.bindListSecondPass(HbmBinder.java:2231)
at org.hibernate.cfg.HbmBinder$ListSecondPass.secondPass(HbmBinder.java:2729)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:43)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1130)
at org.hibernate.cfg.Configuration.generateSchemaUpdateScript(Configuration.java:936)
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:140)
The mapping of the list is creating the problem. What I am doing wrong?
Edit:
This two configuration resides in different file, if these two are placed in same xml then the problem is not occurring.

please add a reference to the mapping file (which maps info.domain.User) into hibernate.cfg.xml.

Please add class level annotations to register the class as a Spring bean, i.e #Entity in this case since you are not using xml configuration.

Related

Hibernate XML Entity Mapping

I have simple definition of my entities, but what i do wrong, because i can not get any entity UserInfo and receive only error (could not load an entity: [UserInfo#2]... )?
P.S.
But query what was traced by Hibernate in console is a valid
select
userinfo0_.primarykey as primaryk1_0_1_,
userinfo0_.firstname as firstnam2_0_1_,
userinfo0_.lastname as lastname3_0_1_,
userinfo0_.birthday as birthday4_0_1_,
userinfode1_.user_id as user_id1_1_0_,
userinfode1_.dep_id as dep_id2_1_0_,
userinfode1_.salary as salary3_1_0_,
userinfode1_.prof as prof4_1_0_
from
SCHEMA.UserInfo userinfo0_
left outer join SCHEMA.UserInfoDetail userinfode1_ on userinfo0_.primarykey = userinfode1_.user_id
<hibernate-mapping>
<class entity-name="UserInfo" schema="SCHEMA" table="UserInfo">
<id column="primarykey" name="primarykey" type="long">
<generator class="identity"/>
</id>
<property column="firstname" name="firstname" type="string"/>
<property column="lastname" name="lastname" type="string"/>
<property column="birthday" name="birthday" type="date"/>
<one-to-one name="UserInfoDetail" class="UserInfoDetail" cascade="save-update"/>
</class>
<class entity-name="UserInfoDetail" schema="SCHEMA" table="UserInfoDetail">
<id column="user_id" name="user_id" type="long">
<generator class="foreign">
<param name="property">UserInfo</param>
</generator>
</id>
<property column="prof" name="prof" type="string"/>
<property column="salary" name="salary" type="long"/>
<property column="dep_id" name="dep_id" type="long"/>
<one-to-one name="UserInfo" class="UserInfo" property-ref="UserInfoDetail" constrained="true"/>
</class>
</hibernate-mapping>

Hibernate pagination ORA-00918: column ambiguously defined

When hibernate tries to paginate an entity generated using the following hbm.xml, it throws up column ambiguously defined.
<class lazy="false" dynamic-update="true" optimistic-lock="all" table="A" name="org.package.Entity">
<cache usage="read-write"/>
<id unsaved-value="null" type="java.lang.Long" name="aId">
<column name="ID_A" not-null="true" sql-type="java.lang.Long"/>
<generator class="org.package.Entity"/>
</id>
<property type="java.lang.Long" name="aGroupId" not-null="true">
<column name="ID_GROUP" not-null="true" sql-type="java.lang.Long"/>
</property>
<property type="java.lang.String" name="statusCode" not-null="true">
<column name="CD_STATUS" not-null="true" sql-type="char(30)" length="30"/>
</property>
<property type="java.lang.Long" name="templateId" not-null="false">
<column name="ID_TEMPLATE" not-null="false" sql-type="java.lang.Long"/>
</property>
<many-to-one name="aGroup" cascade="none" column="Id_Group"
class="org.package.Entity"
insert="false" update="false"/>
<many-to-one name="template" cascade="none" column="ID_TEMPLATE"
class="org.package.Entity"
insert="false" update="false"/>
</class>
What is wrong with this entity definition?
Edit: Turning it into QandA format.
ID_TEMPLATE is being condensed into one column in the query, ID_GROUP isn't.
Hibernate uses a direct string comparison to see if two properties depend on the same column. This is case sensitive, so ID_GROUP was being selected a second time as Id_Group.
Changing the cases to match, it worked.
<class lazy="false" dynamic-update="true" optimistic-lock="all" table="A" name="org.package.Entity">
<cache usage="read-write"/>
<id unsaved-value="null" type="java.lang.Long" name="aId">
<column name="ID_A" not-null="true" sql-type="java.lang.Long"/>
<generator class="org.package.Entity"/>
</id>
<property type="java.lang.Long" name="aGroupId" not-null="true">
<column name="ID_GROUP" not-null="true" sql-type="java.lang.Long"/>
</property>
<property type="java.lang.String" name="statusCode" not-null="true">
<column name="CD_STATUS" not-null="true" sql-type="char(30)" length="30"/>
</property>
<property type="java.lang.Long" name="templateId" not-null="false">
<column name="ID_TEMPLATE" not-null="false" sql-type="java.lang.Long"/>
</property>
<many-to-one name="aGroup" cascade="none" column="ID_GROUP"
class="org.package.Entity"
insert="false" update="false"/>
<many-to-one name="template" cascade="none" column="ID_TEMPLATE"
class="org.package.Entity"
insert="false" update="false"/>
</class>
Maintaining old code is fun. Hope this helps someone.

Hibernate - perform case - select for property

I have two tables in my DB: Customers and Companies.
Mapping for Customer:
<class name="CustomerModel" table="CUSTOMERS" mutable="false">
<cache usage="transactional"/>
<id name="id" type="java.lang.Long">
<column name="ID" precision="19" scale="0"/>
<generator class="assigned"/>
</id>
<many-to-one name="company" not-null="true" column="CUSTOMER_COMP_ID" class="CompanyModel" />
<property name="type" type="CustomerType">
<column name="TYPE"/>
</property>
<property name="fullName" type="string">
<column name="FULL_NAME"/>
</property>
</class>
TYPE column/property can contains two values: PERSON, COMPANY
And for Company:
<class name="CompanyModel" table="COMPANIES" mutable="false">
<cache usage="transactional"/>
<id name="id" type="long">
<column name="ID" precision="19" scale="0" />
</id>
<property name="name" type="string">
<column name="NAME"/>
</property>
</class>
I want to create formula for property fullName in CustomerModel which:
when type = 'PERSON' then fullName = fullName (do not change it)
when type = 'COPMANY' then funnName = company.name
How to create such formula?

Hibernate duplicates record along with null value(new row as duplicate) while saving

I am getting following issue while saving entity in hibernate -
It duplicates the record with null values -
(2661956,2601555,'Chloe','Chloe','Thooks',null,null,null,null,null,null,'Y','N','XYZ',to_date('15-NOV-16','DD-MON-RR'),null,null)
with a duplicate -
(2661946,2601555,null,null,null,null,null,null,null,null,null,'Y','N','XYZ',to_date('15-NOV-16','DD-MON-RR'),null,null) -
We have the following mapping -
Parent -
<?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 default-lazy="false">
<class name="com.sm.persistence.LOADetailBO" table="LOADETAILS">
<id name="loaDetailsId" type="long">
<column name="LOA_ID" precision="38" scale="0"/>
<generator class="com.sm.persistence.dao.seqgen.LOADetailSeqGen">
</generator>
</id>
<many-to-one name="reregistration" class="com.sm.persistence.RerBO" fetch="join">
<column name="RER_ID" precision="38" scale="0"/>
</many-to-one>
<property name="relatedPlanManager" type="string">
<column name="RELATED_PLAN_MANAGER"/>
</property>
<property name="relatedPlanManagerCode" type="string">
<column name="RELATED_PLAN_MANAGER_CODE"/>
</property>
<set name="relatedPlanManagerAddress" inverse="true" cascade="all-delete-orphan">
<key>
<column name="LOA_ID" precision="38" scale="0" not-null="false"/>
</key>
<one-to-many class="com.sm.persistence.AddressBO" />
</set>
<set name="corporateCustomers" inverse="true" cascade="all-delete-orphan">
<key>
<column name="LOA_ID" precision="38" scale="0" not-null="false"/>
</key>
<one-to-many class="com.sm.persistence.CorporateCustomerBO" />
</set>
<set name="privateCustomers" inverse="true" cascade="all-delete-orphan">
<key>
<column name="LOA_ID" precision="38" scale="0" not-null="false" />
</key>
<one-to-many class="com.sm.persistence.PrivateCustomerBO"/>
</set>
<set name="unwrappedAccount" inverse="true" cascade="all-delete-orphan">
<key>
<column name="LOA_ID" precision="38" scale="0" not-null="false"/>
</key>
<one-to-many class="com.sm.persistence.UnwrappedAccountBO" />
</set>
<set name="wrappedAccount" inverse="true" cascade="all-delete-orphan">
<key>
<column name="LOA_ID" precision="38" scale="0" not-null="false" />
</key>
<one-to-many class="com.sm.persistence.WrappedAccountBO"/>
</set>
</class>
</hibernate-mapping>
Child -
<?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 default-lazy="false">
<class name="com.sm.persistence.PrivateCustomerBO" table="RER_CUSTOMER_DETAIL">
<id name="privateCustomerId" type="long">
<column name="RERE_CUSTOMER_ID" precision="38" scale="0"/>
<generator class="com.sm.persistence.dao.seqgen.PrivateCustomerSeqGen">
</generator>
</id>
<many-to-one name="loaDetail" class="com.sm.persistence.LOADetailBO" fetch="join">
<column name="LOA_DETAILS_ID" precision="38" scale="0"/>
</many-to-one>
<property name="title" type="string">
<column name="TITLE"/>
</property>
<property name="firstName" type="string">
<column name="FIRST_NAME"/>
</property>
<property name="surname" type="string">
<column name="SURNAME"/>
</property>
<set name="address" inverse="false" cascade="all-delete-orphan">
<key>
<column name="PRIVATE_CUSTOMER_ID" precision="38" scale="0" not-null="false"/>
</key>
<one-to-many class="com.sm.persistence.AddressBO" />
</set>
<property name="primary" type="string">
<column name="IS_PRIMARY"/>
</property>
<property name="corporate" type="string">
<column name="IS_CORPORATE"/>
</property>
<!--<property name="dateofBirth" type="string">
<column name="DATE_OF_BIRTH"/>
</property>-->
<property name="nationalInsurance" type="string">
<column name="NINO"/>
</property>
</class>
</hibernate-mapping>
I checked parent object both pre and post save and can't find any object with null value populated. However, when I fetch the object hierarchy with criteria api it returns duplicate record with null.
Please guide.
Quick answer:
PrivateCustomerBO is a child of LOADetailBO. So when your java code
saves a PrivateCustomerBO object it will write to all tables
specified against these 2 objects: RER_CUSTOMER_DETAIL = primary
table for PrivateCustomerBO, LOADETAILS = primary table for
LOADetailBO, plus all tables referenced by these two objects via
many-to-one or one-to-many mappings. CORRECT BEHAVIOUR
Expanding the bolded bit above, LOADetailBO is referenced by
PrivateCustomerBO via:
<many-to-one name="loaDetail" class="com.sm.persistence.LOADetailBO" fetch="join">
<column name="LOA_DETAILS_ID" precision="38" scale="0"/>
</many-to-one>
This means that LOADETAILS is additionally referenced as a related
table, not just a parent and a second row is written (in this case
there is some data missing (NULL) because your program hasn't
populated it for the referenced entity). INCORRECT BEHAVIOUR.
Fix: remove the many-to-one mapping shown above (it's redundant and covered by parent).

Hibernate: 2 subclass mapping the same key column

I would like to map the same key column, parent_id this example, across the subclasses. Both ClientProfileDO and BusinessProfileDO are inherited from UserProfileDO. They are on the same table, USERPROFILE. So, they refer the same foreign key on the Contact table. Is it logically incorrect?
<hibernate-mapping package="com.rentorama2.frontpage.client.serialize"default-lazy="false">
<class name="UserProfileDO" table="USERPROFILE">
<id name="oid" type="long" column="oid" >
<generator class="increment">
<param name="initial_value">1</param>
</generator>
</id>
<discriminator column="dcolumn" type="string" length="5"/>
<property name="acctOid">
<column name="acctOid" />
</property>
<property name="email">
<column name="email"/>
</property>
<subclass name="ClientProfileDO" discriminator-value="CP">
<list name="c_contacts" cascade="all">
<key column="parent_id" not-null="true"/>
<index column="idx"/>
<one-to-many class="Contact"/>
</list>
</subclass>
<subclass name="BusinessProfileDO" discriminator-value="BP">
<property name="b_updateAnnouncement">
<column name="updateAnnouncement"/>
</property>
<list name="b_contacts" cascade="all">
<key column="parent_id" not-null="true"/>
<index column="idx"/>
<one-to-many class="Contact"/>
</list>
</subclass>
</class>
I think you should move the Contact one-to-many association into UserProfileDO base class:
<hibernate-mapping package="com.rentorama2.frontpage.client.serialize"default-lazy="false">
<class name="UserProfileDO" table="USERPROFILE">
<id name="oid" type="long" column="oid" >
<generator class="increment">
<param name="initial_value">1</param>
</generator>
</id>
<discriminator column="dcolumn" type="string" length="5"/>
<property name="acctOid">
<column name="acctOid" />
</property>
<property name="email">
<column name="email"/>
</property>
<list name="contacts" cascade="all">
<key column="parent_id" not-null="true"/>
<index column="idx"/>
<one-to-many class="Contact"/>
</list>
<subclass name="ClientProfileDO" discriminator-value="CP">
</subclass>
<subclass name="BusinessProfileDO" discriminator-value="BP">
<property name="b_updateAnnouncement">
<column name="updateAnnouncement"/>
</property>
</subclass>
</class>
And the UserProfileDO class will have a Contact list:
private List<Contact> contacts = new ArrayList<>();
public List<Contact> getContacts() {
return contacts;
}
public void getContacts(List<Contact> contacts) {
this.contacts = contacts;
}

Categories