Common Properties for all Hibernate hbm files? - java

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.

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?

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

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.

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.

remove duplicate rows from database with hibernate

I have an hbm file which is as below:
<?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 auto-import="true" default-lazy="false">
<class name="com.saman.entity.hibernate.EmployeeEntity"
table="Employee" optimistic-lock="version">
<id name="id">
<column name="Id" sql-type="bigint"/>
<generator class="native"/>
</id>
<timestamp name="version" source="db"/>
<property name="firstName">
<column name="FirstName" sql-type="nvarchar(300)"/>
</property>
<property name="lastName">
<column name="LastName" sql-type="nvarchar(300)"/>
</property>
<property name="employeeType">
<column name="EmployeeType" sql-type="nvarchar(300)"/>
</property>
<set name="shifts" table="Shifts" inverse="true" lazy="true" fetch="select">
<key>
<column name="Id" not-null="true"/>
</key>
<one-to-many class="com.saman.entity.hibernate.ShiftEntity"/>
</set>
</class>
</hibernate-mapping>
now I wanted if I add an employee and persist it, if then I add another employee with the previous information, my system raises an exception and tell me that I have another employee in the database with that informations.
does hibernate give me this option?
Well just add this to your mapping
<properties name="firstName_lastName_unique" unique="true">
<property name="firstName"/>
<property name="lastName"/>
</properties>
I think I understand what you want to achieve. But I don't know if you search your problem in stackoverflow first. This might be your answer How to do multiple column UniqueConstraint in hbm?
Have you set an auto increment on the ID column in your database?
You already have a generator for the id value. This should generate a unique id, but it only does so if these two conditions are true:
The column either is defined as autoincrement (p. ex. MySQL) or has a sequence (p. ex. Oracle)
When saving a new row, the member variable id is set to 0.
I can imagine, when you save a new value with previous information, the variable id still has a value != 0, and in this case the database uses the given value instead of generating a new unique one, which will fail due to the unique constraint.
This error also can appear if there is a second unique index on the table.

Hibernate many to one delets all parents when a child is deleted

I have Country and State objects. I intend to have unidirectional many to one relationship from State to Country. I don't want to store any references to States in Country I have defined mapping as below. When I delete even one State object, all Countries are deleted!
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class
name="places.Country"
table="COUNTRY"
dynamic-update="true">
<!-- Technical ID -->
<id name="name" type="string" unsaved-value="new" column="COUNTRY_NAME">
</id>
<!-- Properties -->
<property name="commonName"
column="COMMON_NAME"
/>
<property name="iso2Code"
column="ISO2_CODE"
/>
<property name="iso3Code"
column="ISO3_CODE"
/>
<property name="isoNumeric"
column="ISO_NUMERIC"
/>
<property name="ituCode"
column="ITU_CODE"
/>
<property name="ianaCode"
column="IANA_CODE"
/>
</class>
<class
name="places.State"
table="STATE"
dynamic-update="true">
<!-- Technical ID -->
<id name="name" type="string" unsaved-value="new" column="STATE_NAME">
</id>
<!-- Properties -->
<property name="code" column="STATE_CODE"
/>
<many-to-one name="country" column="COUNTRY" not-null="true" cascade="none"
class="places.Country"
/>
</class>
</hibernate-mapping>
The provided mapping looks fine. Actually, executing the following code using exactly your mapping:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
State aState = (State) session.load(State.class, stateId);
session.delete(aState);
session.getTransaction().commit();
Generates the following output:
...
Hibernate: select state0_.STATE_NAME as STATE1_1_0_, state0_.STATE_CODE as STATE2_1_0_, state0_.COUNTRY as COUNTRY1_0_ from STATE state0_ where state0_.STATE_NAME=?
Hibernate: delete from STATE where STATE_NAME=?
3270 [main] INFO org.hibernate.impl.SessionFactoryImpl - closing
Things are working as expected, my countries are still there.
Maybe show some code?

Categories