Hibernate mapping multiple classes to one table using hbm.xml - java

I am fairly new to Hibernate and need some help with hibernate-mapping.
I have 4 different classes which I want to map into one table, of which the primary key consists of attributes from 2 different classes. At the same time, I want to map only selected attributes from each class into a local database. I wish to avoid JPA annotations and define the mapping style in a hbm.xml file instead. How do I do that?
Take the following example:
public class Tenant implements Serializable {
private final static long serialVersionUID = 1L;
protected List<Rack> rack;
protected String type;
//getters setters
}
public class Rack implements Serializable {
private final static long serialVersionUID = 1L;
protected List<Circuit> circuit;
protected String rackLabel;
protected Boolean excludes;
//getters setters
}
public class Circuit implements Serializable {
private final static long serialVersionUID = 1L;
protected List<CircuitReadings> circuitReadings;
protected String circuitNo;
protected Boolean excludes;
//getters setters
}
public class CircuitReadings
implements Serializable {
private final static long serialVersionUID = 1L;
protected String date;
protected String kva;
protected String current;
protected String kwh;
//getters setters
}
And the eventual table should consist of the following:
type | rackLabel | circuitNo | date | kva | current | energy
"circuitNo" and "date" above should form the composite primary keys.
Can someone show me an example of how I should map this? Thanks!

Hibernate provide a way to map subclass using discriminator keyword.
<class name="Payment" table="PAYMENT">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="native"/>
</id>
<discriminator column="PAYMENT_TYPE" type="string"/>
<property name="amount" column="AMOUNT"/>
...
<subclass name="CreditCardPayment" discriminator-value="CREDIT">
<join table="CREDIT_PAYMENT">
<key column="PAYMENT_ID"/>
<property name="creditCardType" column="CCTYPE"/>
...
</join>
</subclass>
<subclass name="CashPayment" discriminator-value="CASH">
<join table="CASH_PAYMENT">
<key column="PAYMENT_ID"/>
...
</join>
</subclass>
<subclass name="ChequePayment" discriminator-value="CHEQUE">
<join table="CHEQUE_PAYMENT" fetch="select">
<key column="PAYMENT_ID"/>
...
</join>
</subclass>
</class>

There's nothing stopping you from doing that . Create 4 HBMs pointing to the same table but different Pojos . Though it can be done , as #Ioan Alexandru Cucu , it is not recommended .
<!-- HBM1-->
<class name="com.myProject.Rack"
table="My_Table">
<!-- HBM2-->
<class name="com.myProject.Rack"
table="My_Table">

Related

Mapping Hibernate

I have 2 Entities: Technologie and Competence
Each competence can have 1 or more Techno
so i have generate the classes by Hibernate
and he gave me 3 classes Model
Technologie
Competence
TechnologieId
and now i'm confused about how to add a technologie
and what is the point of TechnoligieId ?
Technologie.java
public class Technologie implements java.io.Serializable {
private TechnologieId id;
private Competence competence;
private String libelleTechnologie;
}
TechnologieId.java
public class TechnologieId implements java.io.Serializable {
private int idCompetence;
private int idTechnologie;
}
Technologie.hbm.xml
<class name="com.model.Technologie" table="technologie" catalog="gestioncollaborateur">
<composite-id name="id" class="com.model.TechnologieId">
<key-property name="idCompetence" type="int">
<column name="idCompetence" />
</key-property>
<key-property name="idTechnologie" type="int">
<column name="idTechnologie" />
</key-property>
</composite-id>
<many-to-one name="competence" class="com.model.Competence" update="false" insert="false" fetch="select">
<column name="idCompetence" not-null="true" />
</many-to-one>
<property name="libelleTechnologie" type="string">
<column name="libelleTechnologie" length="254" />
</property>
</class>
If the relationship is mentioned correctly in the question. Then why dont you do something like this?
public class Technologie implements java.io.Serializable {
private id;
private Competence competence;
private String libelleTechnologie;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="<yourForeign Key for Competence>")
public Competence getCompetence() {
return competence;
}
}
And the Competence Class such as.
public class Competence implements java.io.Serializable {
private id;
private List<Technologie> technologies;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(mappedBy = "<name of the property of Competence in Technology class>")
public List<Technologies> getTechnologies() {
return technologies;
}
}
Also, this is if the Technology is the managing side of the relationship. Basically, what it means is you will do a save / update on the Technologie primarily which will handle the relationship.
If you do want the #OneToMany side as the managing side. you would have to add the insertable=false, updatable=false attributes in the #JoinColumn annotation for the the getTechnologies method.

Hibernate mapping: creating FK relation in existing db for join operations

I have an existing db that I cannot alter. There are two tables, one (A) with a PK and one (B) with a FK pointing to the PK of the first. The respective columns are named (A).page_id and (B).cl_from.
In Hibernate mapping i can set an id for the first, mapping the PK. I can also set a bag for the one-to-many relationship.
For the second, I don't need an id, but a many-to-one relationship. How can you set a many-to-one relationship without an id? I don't want to insert an id to the class..
I've tried to set a composite key but had no luck..
// The PK class
<class name="Words" table="PAGE">
<id name="id" column="PAGE_ID" />
<property name="text" column="PAGE_TITLE" />
<bag cascade="all-delete-orphan" inverse="true" lazy="false" name="wordPages">
<key column="PAGE_ID"/>
<one-to-many class="CategoryItems"/>
</bag>
</class>
// The FK class
<class name="CategoryItems" table="CATEGORYLINKS" >
<composite-id>
<key-many-to-one name="id" column="CL_FROM" />
</composite-id>
<property name="text" column="CL_TO" />
</class>
And my classes:
public class Words {
private Long id;
private String text;
private ArrayList wordPages;
// getters - setters
public class CategoryItems implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private String text;
//getters-setters
The latest error i get is: An association from the table CATEGORYLINKS refers to an unmapped class: java.lang.Long
should help with the following code:
public class CategoryItems implements Serializable
{
private static final long serialVersionUID = 1L;
private Words id;
private String text;
//getters-setters
}

Hibernate mapping for superclass

I have to perform hibernate mapping only by using annotation method in subclass according to following scenario in Spring MVC3 enviroment:
1) I have class called Event.java from xxxx.jar library with following properties
public Class Event{
public integer id;
public String start_date;
public String start_date;
public String text;
}
2) POJO class CustomEvent.java extending Event.java class using inheritance with following structure.
public class CustomEvent extends Event implements Serializable {
private static final long serialVersionUID = 1L;
public String user;
public String type;
public String contact;
public String status;
}
3) Im able to perform hibernate mapping using XML in following way
<hibernate-mapping>
<class name="<package>.model.CustomEvent" table="events">
<id column="event_id" name="id" type="java.lang.Integer">
<generator class="increment"/>
</id>
<property column="start_date" name="start_date" type="timestamp"/>
<property column="end_date" name="end_date" type="timestamp"/>
<property column="text" name="text" type="java.lang.String"/>
<property column="user" name="user" type="java.lang.String"/>
<property column="type" name="type" type="java.lang.String"/>
<property column="contact" name="contact" type="java.lang.String"/>
<property column="status" name="status" type="java.lang.String"/>
</class>
</hibernate-mapping>
and its working fine.
Q) How I can achieve the same thing with JPA/Hibernate annotations?
I am new bay for Hibernate / Spring framework.
Note: Event class is present in .jar library, not able to see the code exactly

can we map non-object propety to an object in Many-to-one relationship of hibernate?

I have a very specific scenario as follow.
public class Person
{
Long id;
Collection<PersonRelation> personRelationCollection = new LinkedHashSet<PersonRelation>();
/**
has respective getter and setter
**/
}
public class PersonRelation
{
Long id;
Long parentPersonId; // here I don't want parentPersonId of type Person
Long childPersonId; // here also I don't want childPersonId of type Person
String relationType;
/**
has respective getter setter
**/
}
In my mapping files I have following
<class name="Person" table="PERSON">
<id name="id" column="IDENTIFIER">
<generator class="native"/>
</id>
<set
name="personRelationCollection"
table="PERSON_RELATION"
cascade="all"
>
<key column="PARENT_PERSON_ID"/>
<one-to-many class="PersonRelation"/>
</set>
</class>
and
<class name="PersonRelation" table="PERSON_RELATION">
<id name="id" column="IDENTIFIER">
<generator class="native"/>
</id>
<!-- following many-to-one mapping doesn't work-->
<!-- I need help here to satisfy my requirement -->
<many-to-one
name="parentPersonId"
column="PARENT_PERSON_ID"
class="Person"
not-null="true"/>
<Property name="childPersonId" column="CHILD_PERSON_ID"/>
<property name="relationType" column="RELATION_TYPE"/>
</class>
In this example, as in PersonRelation class, attribute parentPersonId is Long and not type of Person, I'm getting
org.hibernate.MappingException: Association references unmapped class PersonRelation
$
Please help.
Forget about references by id. In Hibernate you work with objects, not tables.
I guess your code could be written like this:
#Entity
#Table(name="your_table")
public class Item{
private Long id;
private Item parentItem;
private List<Item> children;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public Long getId(){
}
#ManyToOne()//Your options
public Item getParentItem(){
}
#OneToMane(mappedBy="parentItem")
public List<Item> getChildren(){
}
//Setters omitted
}
finally i found answer my own. Very small thing we have to do as follow.
<class name="PersonRelation" table="PERSON_RELATION">
<id name="id" column="IDENTIFIER">
<generator class="native"/>
</id>
<!-- here remove many-to-one mapping ---- it's not needed-->
<!-- treet participantPersonId as a simple property and everything will work -->
<Property name="parentPersonId" column="PARENT_PERSON_ID" type="Long"/>
<Property name="childPersonId" column="CHILD_PERSON_ID"/>
<property name="relationType" column="RELATION_TYPE"/>
</class>
This works perfectly fine. :)
Here, when you insert Person object, then it will not inset PersonRelation object too. You have to explicitly insert PersonRelation object. Perhaps, when we retrieve Person object, then it will gives you collection of PersonRelation. Here no need to retrieve PersonRelation collection explicitly.

Persisting LinkedList in Hibernate

I am trying to persist a Class with a LinkedList Attribute but can't seem to get it right. Here is my code and my mapping:
import java.util.LinkedList;
public class Stuff implements java.io.Serializable {
private long id;
private LinkedList<Image> images;
public Stuff() {
}
public Stuff(long Id) {
id = Id;
}
public long getId() {
return id;
}
public void setId(long mealId) {
id = mealId;
}
public LinkedList<Image> getNumberImages(int number) {
assert (number >= 0);
return (LinkedList<Image>) images.subList(0, number) ;
}
public LinkedList<Image> getImages() {
return images;
}
public LinkedList<Image> setImages(LinkedList<Image> images) {
this.images = images;
}
public void addImage(Image image) {
if (!images.contains(image)) {
images.add(image);
}
}
Hibernate mapping:
<hibernate-mapping>
<class name="data.Stuff" table="Stuff">
<id name="id" type="long" access="field">
<column name="ID" />
<generator class="assigned" />
</id>
<list name="images" inverse="false" table="IMAGE" lazy="true" access="field">
<key>
<column name="ID" />
</key>
<list-index></list-index>
<one-to-many class="data.Image" />
</list>
</class>
</hibernate-mapping>
It seems I can persist objects of the Class Stuff like this but when I try to recover them the following error occurres :
Hibernate: select stuff0_.ID as ID0_, stuff0_.NAME as NAME0_, meal0_.GROUPING as GROUPING0_ from MEAL meal0_
org.hibernate.PropertyAccessException: could not set a field value by reflection setter of data.Meal.images
Generally, Hibernate will provide its own implementations for collections so you should prefer interfaces to specific implementations. It's probably attempting to assign a different kind of list to images and failing. You would have to change your field to List<Image>.
Hibernate (and JPA in general) persists collections using their interfaces. The list must be declared as a List, and not as a LinkedList. And it won't be loaded with a LinkedList instance, because Hibernate uses its own List implementation to implement dirty-checking, lazy-loading, etc.
It's a good practice to program on interfaces rather than programming on concrete implementations in general. In JPA entities, it's mandatory.

Categories

Resources