first problem with the mismatch of the world of object-oriented and relational occurs when modeling (mapping) a hierarchy of classes. Inheritance is one of the paradigms of object-oriented programming and the abandonment of him, because of the relational data layer, it would be regression. Using Hibernate inheritance can be mapped in three ways: first
table for each class (table per concrete class)
second table for each class hierarchy (table per class hierarchy)
third table for each subclass (table per subclass)
In all cases, I will perform the method:
public class Main {public static
void main (String [] args) {Session session
= null;
SessionFactory = new SessionFactory Configuration (.) configure (). buildSessionFactory ();
session = sessionFactory.openSession();
Subcategory1 cat = new Subcategory1();
cat.setName("sub1");
cat.setSize(1);
Subcategory2 cat2 = new Subcategory2();
cat2.setName("sub2");
cat2.setVolume(2);
session.beginTransaction();
session.save(cat);
session.save(cat2);
session.flush();
session.getTransaction().commit();
session.close();
session = sessionFactory.openSession();
session.beginTransaction();
List<Category> cats = session.createQuery("from Subcategory1").list();
System.out.println(cats.size());
cats = session.createQuery("from Subcategory2").list();
System.out.println(cats.size());
}
}
public class Category {
Integer id;
String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Subcategory1 extends Category {
Integer id;
Integer size;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}
public class Subcategory2 extends Category {
Integer id;
Integer volume;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
} Public Integer
getVolume () {return
volume;
} public void
setVolume (Integer volume) {
this.volume = volume;
}}
Ad 1
simplest approach - the database in general are not aware of the inheritance.
consists of two files mapping Subcategory1.hbm.xml, Subcategory2.hbm.xml:
\u0026lt;? Xml version = "1.0"?>
\u0026lt;! DOCTYPE hibernate-mapping PUBLIC
"- / / Hibernate / Hibernate Mapping DTD 3.0 / / EN "
" http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd ">
<hibernate-mapping package="main">
<class name="Subcategory1">
<id name="id" unsaved-value="null" column="category_id">
<generator class="sequence">
<param name="sequence">sub1_category_seq</param>
</generator>
</id>
<property name="name"/>
<property name="size"/>
</class>
</hibernate-mapping>
<?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 package="main">
<class name="Subcategory2">
<id name="id" unsaved-value="null" column="category_id">
<generator class="sequence">
<param name="sequence">sub2_category_seq</param>
</generator>
</id>
<property name="name"/>
<property name="volume"/>
</class>
</hibernate-mapping>
Stworzone zostaly dwie tabele:
CREATE TABLE subcategory1
(
category_id integer NOT NULL,
name character varying(255),
size integer,
CONSTRAINT subcategory1_pkey PRIMARY KEY (category_id)
)
CREATE TABLE subcategory2
(
category_id integer NOT NULL,
name character varying(255),
volume integer,
Subcategory2_pkey CONSTRAINT PRIMARY KEY (category_id)
)
Ad2.
second approach - mapping of the entire hierarchy of classes in a single table.
form a single file mapping Category.hbm.xml
\u0026lt;? Xml version = "1.0"?>
\u0026lt;! DOCTYPE hibernate-mapping PUBLIC
"- / / Hibernate / Hibernate Mapping DTD 3.0 / / EN "
" http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd ">
\u0026lt;hibernate-mapping package="main">
\u0026lt;class name="Category">
\u0026lt;id name = "id" unsaved-value = "null" column="category_id">
<generator class="sequence">
<param name="sequence">category_seq</param>
</generator>
</id>
<discriminator column="type" type="string" />
<property name="name" />
<subclass name="Subcategory1" discriminator-value="1">
<property name="size" />
</subclass>
<subclass name="Subcategory2" discriminator-value="2">
\u0026lt;property name="volume" />
\u0026lt;/ subclass>
\u0026lt;/ class>
\u0026lt;/ hibernate-mapping>
was created a table:
CREATE TABLE category (
category_id integer NOT NULL,
"type" character varying (255) NOT NULL, name character varying
(255),
size integer, integer
volume,
category_pkey CONSTRAINT PRIMARY KEY (category_id)
)
Important! When creating the mapping file, be sure to element \u0026lt;discriminator> was in before all the elements \u0026lt;PROPERTY>.
Ad 3
third approach involves the representation of inheritance relationships with foreign keys of relational links. Each subclass uses its own table. I create three files
mapping Category.hbm.xml, Subcategory1.hbm.xml, Subcategory2.hbm.xml
\u0026lt;? Xml version = "1.0"?>
\u0026lt;! DOCTYPE hibernate-mapping PUBLIC
"- / / Hibernate / Hibernate Mapping DTD 3.0 / / EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
\u0026lt;hibernate-mapping package="main">
<class name="Category">
<id name="id" unsaved-value="null" column="category_id">
<generator class="sequence">
<param name="sequence">category_seq</param>
</generator>
</id>
<property name="name" />
</class>
</hibernate-mapping>
<?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 package="main">
<joined-subclass name="Subcategory1" extends="Category">
<key column="category_id"/>
<property name="size"/>
</joined-subclass>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0 / / EN "
" http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd ">
\u0026lt;hibernate-mapping package="main">
\u0026lt;joined-subclass name = "Subcategory2" extends = "Category">
\u0026lt;key column="category_id"/>
\u0026lt;property name="volume"/>
\u0026lt;/ joined-subclass>
\u0026lt;/ hibernate-mapping>
in the database have been created three tables:
CREATE TABLE category (category_id
integer NOT NULL, name character varying
(255),
CONSTRAINT category_pkey PRIMARY KEY (category_id)
)
CREATE TABLE subcategory1
(
category_id integer NOT NULL,
size integer,
CONSTRAINT subcategory1_pkey PRIMARY KEY (category_id),
CONSTRAINT fk6c9080d3884719af FOREIGN KEY (category_id)
REFERENCES category (category_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE subcategory2
(
category_id integer NOT NULL,
volume integer,
CONSTRAINT subcategory2_pkey PRIMARY KEY (category_id),
CONSTRAINT fk6c9080d4884719af FOREIGN KEY (category_id)
REFERENCES category (category_id) MATCH
SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION
)
This type of mapping can be issued intuitive polymorphic queries:
session.createQuery cats = ("from Category"). List ();
System.out. println (cats.size ()); / / "2"
Each entry in the table and subcategory2 subcategory1 will correspond to an entry in the category table.
0 comments:
Post a Comment