Hibernate mapping xml one-to-one (many-to-one) - java

I'm trying to map a relationship between two classes which have a one-to-one relationship. After looking up on the internet it seems like people prefer to map it using many-to-one.
For example have have a class Order and a class Bill. Bill holds a FK to the invoice.
Here is my mapping for Bill:
<?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 Mar 21, 2016 10:46:20 PM by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="domain.Bill" table="BILL">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<many-to-one name="order" class="domain.Order" column="ORDER_ID" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
As you can see above, in my mapping of Bill I can specify the column of Fk to the Order, but what should I put in my mapping for Order since it does not have a Fk to Bill?
<?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 Mar 21, 2016 10:46:20 PM by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="domain.Order" table="ORDER">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<many-to-one name="bill" class="domain.Bill" ???? fetch="select"/>
</class>
</hibernate-mapping>

You should try to map it as it is: one-to-one.
The only reason that I am aware of why people may recommend many-to-one is because of the lazy loading issues on the inverse side of the one-to-one associations. Then you probably want a fake one-to-many association on the inverse side (after all it's the only logical inverse side of many-to-one).
However, take a look at this answer for different alternatives.

Related

Hibernate mapping - The content of element type "class" must match "(meta*,subselect

I've a problem with the mapping of a class on hibernate...
I've already checked on the web, but i don't find the same problem
This is the error:
The content of element type "class" must match "(meta*,subselect?,cache?,synchronize*,comment?,tuplizer*,(id|
composite-id),discriminator?,natural-id?,(version|timestamp)?,(property|many-to-one|one-to-one|component|dynamic-
component|properties|any|map|set|list|bag|idbag|array|primitive-array)*,((join*,subclass*)|joined-subclass*|union-
subclass*),loader?,sql-insert?,sql-update?,sql-delete?,filter*,fetch-profile*,resultset*,(query|sql-query)*)".
and this is my code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="it.****.extractor.application.DGEPRA" table="T_DGEPRA_LOG">
<id name="id" type="int" column="ID"/>
<property name="time" column="TIME" type="timestamp"/>
<property name="function" column="FUNCTION" type="string"/>
<property name="executionTime" column="EXECUTION_TIME" type="int"/>
<property name="guId" column="GUID" type="string"/>
</class>
</hibernate-mapping>
any idea?

What is wrong with this code that saves value objects?

I have two entities and two value objects - Employee, Card, Employee Number & Card Number. The relationship between Employee and Card is a one-to-many. I create an instance of Employee and an instance of Card like so and save them to the database...
EmployeeRepositoryHibernate employeeRepository = new EmployeeRepositoryHibernate();
employeeRepository.setSessionFactory();
employeeRepository.getSession().beginTransaction();
EmployeeNumber employeeNumber = new EmployeeNumber("MNO");
Location location = new Location("Room 1");
CardNumber cardNumber = new CardNumber("1");
Employee employee = new Employee(employeeNumber, location);
Card card = new Card(cardNumber, "1111", employee);
employeeRepository.getSession().save(employee);
employeeRepository.getSession().save(card);
employeeRepository.getSession().getTransaction().commit();
employeeRepository.getSession().close();
Except, it won't save, the following error message is shown... I can save an employee, but the message is thrown when I try to save a related card... the mysql database isn't relational yet.. both tables are separate...
Problem fixed: required related tables.
Caused by: java.sql.SQLException: Field 'employeeNumber' doesn't have a default value
Here are the two Hibernate XML mapping files for Card and Employee...
Card
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-access="field">
<class name="model.Card" table="Card">
<id name="CardID" type="long">
<column name="CardID" />
<generator class="identity" />
</id>
<component name="cardNumber" unique="true">
<property name="number" column="cardNumber"/>
</component>
<many-to-one name="employee" class="model.Employee" fetch="select">
<column name="EmpID" not-null="true"></column>
</many-to-one>
<property name="PIN" column="PIN"/>
</class>
</hibernate-mapping>
Employee
<?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-access="field">
<class name="model.Employee" table="employee">
<id name="EmpID" column="EmpID">
<generator class="org.hibernate.id.IdentityGenerator"/>
</id>
<component name="employeeNumber" class="model.EmployeeNumber" >
<property name="number" column="employeeNumber" type="string"/>
</component>
<component name="location">
<property name="location" column="Location" type="string"/>
</component>
<set name="cards" inverse="true" cascade="all">
<key>
<column name="EmpID" not-null="true"></column>
</key>
<one-to-many class="model.Card"/>
</set>
</class>
</hibernate-mapping>
One of these might help:
Add a default value to the column employeeNumber
ALTER TABLE 'table_name' ALTER 'employeeNumber' SET DEFAULT NULL
Use auto increment if you are using employeeNumber as a primary key.
Supply value to the employeeNumber column during insertion.

Version of the parent object does not change when its child object's state changes

I am using Hibernate3
I have a simple one to many relationship(Parent object has as set of child objects)
if the child objects are added/removed, the version of the parent object is updated where as if the state of the child object is changed, the version of the parent is not getting updated.
Here is the mapping -
Category.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.codejava.hibernate">
<class name="Category" table="CATEGORY">
<id name="id" column="CATEGORY_ID">
<generator class="native"/>
</id>
<property name="name" column="NAME" />
<version name="version" type="integer" column="version" unsaved-value="null" />
<set name="products" inverse="true" cascade="all-delete-orphan">
<key column="CATEGORY_ID" not-null="true" />
<one-to-many class="Product"/>
</set>
</class>
Product.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.codejava.hibernate">
<class name="Product" table="PRODUCT">
<id name="id" column="PRODUCT_ID">
<generator class="native"/>
</id>
<version name="version" type="integer" column="version" unsaved-value="null" />
<property name="name" column="NAME" />
<property name="description" column="DESCRIPTION" />
<property name="price" column="PRICE" type="float" />
<many-to-one name="category" class="Category"
column="CATEGORY_ID" not-null="true"/>
</class>
When the Product changes, Product.version is updated properly but the Category.version remains the same.
I assume this is a cross cutting concern and there has to be a plausible solution for this. I did a lot of searching and could not find one. Please help me out
Yes, this is just a limitation of the way hibernate works, I'm afraid. The only solution is to change it on both sides when you need to make a change.
You could also refresh the parent, but bear in mind that that will hit the database.
It's probably a subjective opinion, but to me it seems logical this way. However, one common way of handling this is to have something like lastUpdated field on parent entity, which you would set each time before calling update on it. This can be done in #PrePersist and/or #PreUpdate, and it would ensure that entity version changes whenever you update it, regardless of what changes are made to it or its relations.

Common Properties for all Hibernate hbm files?

I am using Hibernate 4.02.
What i want to do is I want to include some common Hbm mapping to all my hbm files.
e.g Account,Contact hbm.xml files have there own files Id,Name etc.
What i want to do is add some common properites like ModifiedBy and CreatedBy to all these hbm files.
You can define external entities for your xml files. This is not a hibernate specific feature but an xml one. Check this.
You can specify a common .hbm file with the common properties and then import that in all of your other hbm files.
For example, you can create a file named commonProperties.hbm in your classpath with the following content
<property name="created" type="timestamp" not-null="true" />
<property name="lastUpdated" type="timestamp" not-null="true"/>
And then in your other hbm file, for example in Person.hbm.xml you can import the above hbm file as shown below
<?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"
[<!ENTITY commonProperties SYSTEM "classpath://path/to/commonProperties.hbm">]
>
<hibernate-mapping>
<class name="com.example.Person" table="person">
....
<id name="id" column="personid">
<generator class="native" />
</id>
&commonProperties;
<property name="name" column="name" not-null="true" unique="true" length="230" />
....
....
....
Hope this helps.

Relationship set between table and mapping table to use joins

I have two tables: a "Module" table and a "StaffModule" table. I want to display a list of modules by which staff are present on the staffmodule mapping table.
I've tried
from Module join Staffmodule sm with ID = sm.MID
with no luck, I get the following error
Path Expected for join!
However, I thought I had the correct join too allow this, but this is obviously not the case. Can any one help?
StaffModule HBM
<?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">
<!-- Generated Apr 26, 2010 9:50:23 AM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class name="Hibernate.Staffmodule" schema="WALK" table="STAFFMODULE">
<composite-id class="Hibernate.StaffmoduleId" name="id">
<key-many-to-one name="mid" class="Hibernate.Module">
<column name="MID"/>
</key-many-to-one>
<key-property name="staffid" type="int">
<column name="STAFFID"/>
</key-property>
</composite-id>
</class>
</hibernate-mapping>
and Module.HBM
<?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">
<!-- Generated Apr 26, 2010 9:50:23 AM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
<class name="Hibernate.Module" schema="WALK" table="MODULE">
<id name="id" type="int">
<column name="ID"/>
<generator class="assigned"/>
</id>
<property name="modulename" type="string">
<column length="50" name="MODULENAME"/>
</property>
<property name="teacherid" type="int">
<column name="TEACHERID" not-null="true"/>
</property>
</class>

Categories